113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#include <stdlib.h>
213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#include <stddef.h>
313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#include <string.h>
413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#include <netinet/in.h>
513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#include <arpa/inet.h>
613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#include <errno.h>
713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#include "node_internal.h"
913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#include "context_internal.h"
1013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#include "debug.h"
1113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
1213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindlestruct sepol_node {
1313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
1413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	/* Network address and mask */
1513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	char *addr;
1613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	size_t addr_sz;
1713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
1813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	char *mask;
1913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	size_t mask_sz;
2013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
2113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	/* Protocol */
2213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	int proto;
2313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
2413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	/* Context */
2513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	sepol_context_t *con;
2613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle};
2713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
2813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindlestruct sepol_node_key {
2913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
3013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	/* Network address and mask */
3113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	char *addr;
3213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	size_t addr_sz;
3313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
3413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	char *mask;
3513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	size_t mask_sz;
3613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
3713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	/* Protocol */
3813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	int proto;
3913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle};
4013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
4113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle/* Converts a string represtation (addr_str)
4213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * to a numeric representation (addr_bytes) */
4313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
4413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindlestatic int node_parse_addr(sepol_handle_t * handle,
4513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle			   const char *addr_str, int proto, char *addr_bytes)
4613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{
4713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
4813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	switch (proto) {
4913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
5013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	case SEPOL_PROTO_IP4:
5113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		{
5213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle			struct in_addr in_addr;
5313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
5413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle			if (inet_pton(AF_INET, addr_str, &in_addr) <= 0) {
5513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle				ERR(handle, "could not parse IPv4 address "
5613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle				    "%s: %s", addr_str, strerror(errno));
5713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle				return STATUS_ERR;
5813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle			}
5913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
6013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle			memcpy(addr_bytes, &in_addr.s_addr, 4);
6113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle			break;
6213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		}
6313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	case SEPOL_PROTO_IP6:
6413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		{
6513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle			struct in6_addr in_addr;
6613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
6713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle			if (inet_pton(AF_INET6, addr_str, &in_addr) <= 0) {
6813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle				ERR(handle, "could not parse IPv6 address "
6913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle				    "%s: %s", addr_str, strerror(errno));
7013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle				return STATUS_ERR;
7113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle			}
7213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
7384f6ac246f5980f831a5777d53c0a0bd6ad17d3cStephen Smalley#ifdef DARWIN
7484f6ac246f5980f831a5777d53c0a0bd6ad17d3cStephen Smalley			memcpy(addr_bytes, in_addr.s6_addr, 16);
7584f6ac246f5980f831a5777d53c0a0bd6ad17d3cStephen Smalley#else
7613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle			memcpy(addr_bytes, in_addr.s6_addr32, 16);
7784f6ac246f5980f831a5777d53c0a0bd6ad17d3cStephen Smalley#endif
7813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle			break;
7913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		}
8013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	default:
8113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		ERR(handle, "unsupported protocol %u, could not "
8213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		    "parse address", proto);
8313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		return STATUS_ERR;
8413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	}
8513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
8613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	return STATUS_SUCCESS;
8713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle}
8813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
8913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle/* Allocates a sufficiently large buffer (addr, addr_sz)
9013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * according the the protocol */
9113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
9213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindlestatic int node_alloc_addr(sepol_handle_t * handle,
9313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle			   int proto, char **addr, size_t * addr_sz)
9413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{
9513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
9613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	char *tmp_addr = NULL;
9713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	size_t tmp_addr_sz;
9813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
9913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	switch (proto) {
10013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
10113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	case SEPOL_PROTO_IP4:
10213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		tmp_addr_sz = 4;
10313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		tmp_addr = malloc(4);
10413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		if (!tmp_addr)
10513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle			goto omem;
10613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		break;
10713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
10813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	case SEPOL_PROTO_IP6:
10913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		tmp_addr_sz = 16;
11013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		tmp_addr = malloc(16);
11113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		if (!tmp_addr)
11213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle			goto omem;
11313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		break;
11413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
11513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	default:
11613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		ERR(handle, "unsupported protocol %u", proto);
11713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		goto err;
11813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	}
11913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
12013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	*addr = tmp_addr;
12113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	*addr_sz = tmp_addr_sz;
12213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	return STATUS_SUCCESS;
12313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
12413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle      omem:
12513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	ERR(handle, "out of memory");
12613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
12713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle      err:
12813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	free(tmp_addr);
12913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	ERR(handle, "could not allocate address of protocol %s",
13013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	    sepol_node_get_proto_str(proto));
13113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	return STATUS_ERR;
13213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle}
13313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
13413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle/* Converts a numeric representation (addr_bytes)
13513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * to a string representation (addr_str), according to
13613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * the protocol */
13713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
13813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindlestatic int node_expand_addr(sepol_handle_t * handle,
13913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle			    char *addr_bytes, int proto, char *addr_str)
14013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{
14113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
14213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	switch (proto) {
14313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
14413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	case SEPOL_PROTO_IP4:
14513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		{
14613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle			struct in_addr addr;
14713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle			memset(&addr, 0, sizeof(struct in_addr));
14813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle			memcpy(&addr.s_addr, addr_bytes, 4);
14913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
15013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle			if (inet_ntop(AF_INET, &addr, addr_str,
15113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle				      INET_ADDRSTRLEN) == NULL) {
15213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
15313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle				ERR(handle,
15413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle				    "could not expand IPv4 address to string: %s",
15513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle				    strerror(errno));
15613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle				return STATUS_ERR;
15713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle			}
15813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle			break;
15913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		}
16013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
16113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	case SEPOL_PROTO_IP6:
16213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		{
16313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle			struct in6_addr addr;
16413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle			memset(&addr, 0, sizeof(struct in6_addr));
16584f6ac246f5980f831a5777d53c0a0bd6ad17d3cStephen Smalley#ifdef DARWIN
16684f6ac246f5980f831a5777d53c0a0bd6ad17d3cStephen Smalley			memcpy(&addr.s6_addr[0], addr_bytes, 16);
16784f6ac246f5980f831a5777d53c0a0bd6ad17d3cStephen Smalley#else
16813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle			memcpy(&addr.s6_addr32[0], addr_bytes, 16);
16984f6ac246f5980f831a5777d53c0a0bd6ad17d3cStephen Smalley#endif
17013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle			if (inet_ntop(AF_INET6, &addr, addr_str,
17113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle				      INET6_ADDRSTRLEN) == NULL) {
17213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
17313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle				ERR(handle,
17413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle				    "could not expand IPv6 address to string: %s",
17513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle				    strerror(errno));
17613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle				return STATUS_ERR;
17713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle			}
17813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle			break;
17913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		}
18013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
18113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	default:
18213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		ERR(handle, "unsupported protocol %u, could not"
18313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		    " expand address to string", proto);
18413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		return STATUS_ERR;
18513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	}
18613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
18713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	return STATUS_SUCCESS;
18813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle}
18913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
19013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle/* Allocates a sufficiently large address string (addr)
19113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * according to the protocol */
19213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
19313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindlestatic int node_alloc_addr_string(sepol_handle_t * handle,
19413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle				  int proto, char **addr)
19513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{
19613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
19713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	char *tmp_addr = NULL;
19813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
19913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	switch (proto) {
20013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
20113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	case SEPOL_PROTO_IP4:
20213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		tmp_addr = malloc(INET_ADDRSTRLEN);
20313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		if (!tmp_addr)
20413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle			goto omem;
20513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		break;
20613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
20713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	case SEPOL_PROTO_IP6:
20813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		tmp_addr = malloc(INET6_ADDRSTRLEN);
20913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		if (!tmp_addr)
21013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle			goto omem;
21113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		break;
21213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
21313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	default:
21413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		ERR(handle, "unsupported protocol %u", proto);
21513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		goto err;
21613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	}
21713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
21813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	*addr = tmp_addr;
21913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	return STATUS_SUCCESS;
22013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
22113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle      omem:
22213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	ERR(handle, "out of memory");
22313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
22413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle      err:
22513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	free(tmp_addr);
22613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	ERR(handle, "could not allocate string buffer for "
22713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	    "address of protocol %s", sepol_node_get_proto_str(proto));
22813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	return STATUS_ERR;
22913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle}
23013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
23113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle/* Key */
23213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindleint sepol_node_key_create(sepol_handle_t * handle,
23313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle			  const char *addr,
23413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle			  const char *mask,
23513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle			  int proto, sepol_node_key_t ** key_ptr)
23613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{
23713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
23813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	sepol_node_key_t *tmp_key =
23913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	    (sepol_node_key_t *) calloc(1, sizeof(sepol_node_key_t));
24013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	if (!tmp_key)
24113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		goto omem;
24213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
24313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	if (node_alloc_addr(handle, proto, &tmp_key->addr, &tmp_key->addr_sz) <
24413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	    0)
24513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		goto err;
24613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	if (node_parse_addr(handle, addr, proto, tmp_key->addr) < 0)
24713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		goto err;
24813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
24913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	if (node_alloc_addr(handle, proto, &tmp_key->mask, &tmp_key->mask_sz) <
25013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	    0)
25113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		goto err;
25213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	if (node_parse_addr(handle, mask, proto, tmp_key->mask) < 0)
25313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		goto err;
25413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
25513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	tmp_key->proto = proto;
25613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
25713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	*key_ptr = tmp_key;
25813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	return STATUS_SUCCESS;
25913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
26013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle      omem:
26113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	ERR(handle, "out of memory");
26213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
26313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle      err:
26413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	sepol_node_key_free(tmp_key);
26513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	ERR(handle, "could not create node key for (%s, %s, %s)",
26613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	    addr, mask, sepol_node_get_proto_str(proto));
26713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	return STATUS_ERR;
26813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle}
26913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
27013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindlehidden_def(sepol_node_key_create)
27113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
27213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindlevoid sepol_node_key_unpack(const sepol_node_key_t * key,
27313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle			   const char **addr, const char **mask, int *proto)
27413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{
27513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
27613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	*addr = key->addr;
27713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	*mask = key->mask;
27813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	*proto = key->proto;
27913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle}
28013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
28113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindlehidden_def(sepol_node_key_unpack)
28213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
28313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindleint sepol_node_key_extract(sepol_handle_t * handle,
28413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle			   const sepol_node_t * node,
28513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle			   sepol_node_key_t ** key_ptr)
28613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{
28713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
28813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	sepol_node_key_t *tmp_key =
28913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	    (sepol_node_key_t *) calloc(1, sizeof(sepol_node_key_t));
29013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	if (!tmp_key)
29113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		goto omem;
29213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
29313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	tmp_key->addr = malloc(node->addr_sz);
29413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	tmp_key->mask = malloc(node->mask_sz);
29513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
29613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	if (!tmp_key->addr || !tmp_key->mask)
29713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		goto omem;
29813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
29913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	memcpy(tmp_key->addr, node->addr, node->addr_sz);
30013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	memcpy(tmp_key->mask, node->mask, node->mask_sz);
30113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	tmp_key->addr_sz = node->addr_sz;
30213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	tmp_key->mask_sz = node->mask_sz;
30313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	tmp_key->proto = node->proto;
30413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
30513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	*key_ptr = tmp_key;
30613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	return STATUS_SUCCESS;
30713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
30813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle      omem:
30913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	sepol_node_key_free(tmp_key);
31013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	ERR(handle, "out of memory, could not extract node key");
31113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	return STATUS_ERR;
31213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle}
31313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
31413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindlevoid sepol_node_key_free(sepol_node_key_t * key)
31513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{
31613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
31713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	if (!key)
31813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		return;
31913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
32013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	free(key->addr);
32113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	free(key->mask);
32213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	free(key);
32313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle}
32413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
32513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindlehidden_def(sepol_node_key_free)
32613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
32713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindleint sepol_node_compare(const sepol_node_t * node, const sepol_node_key_t * key)
32813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{
32913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
33013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	int rc1, rc2;
33113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
33213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	if ((node->addr_sz < key->addr_sz) || (node->mask_sz < key->mask_sz))
33313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		return -1;
33413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
33513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	else if ((node->addr_sz > key->addr_sz) ||
33613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		 (node->mask_sz > key->mask_sz))
33713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		return 1;
33813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
33913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	rc1 = memcmp(node->addr, key->addr, node->addr_sz);
34013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	rc2 = memcmp(node->mask, key->mask, node->mask_sz);
34113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
34213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	return (rc2 != 0) ? rc2 : rc1;
34313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle}
34413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
34513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindleint sepol_node_compare2(const sepol_node_t * node, const sepol_node_t * node2)
34613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{
34713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
34813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	int rc1, rc2;
34913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
35013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	if ((node->addr_sz < node2->addr_sz) ||
35113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	    (node->mask_sz < node2->mask_sz))
35213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		return -1;
35313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
35413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	else if ((node->addr_sz > node2->addr_sz) ||
35513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		 (node->mask_sz > node2->mask_sz))
35613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		return 1;
35713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
35813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	rc1 = memcmp(node->addr, node2->addr, node->addr_sz);
35913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	rc2 = memcmp(node->mask, node2->mask, node->mask_sz);
36013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
36113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	return (rc2 != 0) ? rc2 : rc1;
36213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle}
36313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
36413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle/* Addr */
36513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindleint sepol_node_get_addr(sepol_handle_t * handle,
36613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle			const sepol_node_t * node, char **addr)
36713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{
36813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
36913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	char *tmp_addr = NULL;
37013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
37113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	if (node_alloc_addr_string(handle, node->proto, &tmp_addr) < 0)
37213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		goto err;
37313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
37413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	if (node_expand_addr(handle, node->addr, node->proto, tmp_addr) < 0)
37513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		goto err;
37613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
37713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	*addr = tmp_addr;
37813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	return STATUS_SUCCESS;
37913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
38013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle      err:
38113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	free(tmp_addr);
38213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	ERR(handle, "could not get node address");
38313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	return STATUS_ERR;
38413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle}
38513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
38613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindlehidden_def(sepol_node_get_addr)
38713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
38813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindleint sepol_node_get_addr_bytes(sepol_handle_t * handle,
38913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle			      const sepol_node_t * node,
39013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle			      char **buffer, size_t * bsize)
39113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{
39213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
39313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	char *tmp_buf = malloc(node->addr_sz);
39413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	if (!tmp_buf) {
39513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		ERR(handle, "out of memory, could not get address bytes");
39613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		return STATUS_ERR;
39713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	}
39813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
39913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	memcpy(tmp_buf, node->addr, node->addr_sz);
40013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	*buffer = tmp_buf;
40113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	*bsize = node->addr_sz;
40213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	return STATUS_SUCCESS;
40313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle}
40413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
40513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindlehidden_def(sepol_node_get_addr_bytes)
40613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
40713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindleint sepol_node_set_addr(sepol_handle_t * handle,
40813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle			sepol_node_t * node, int proto, const char *addr)
40913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{
41013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
41113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	char *tmp_addr = NULL;
41213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	size_t tmp_addr_sz;
41313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
41413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	if (node_alloc_addr(handle, proto, &tmp_addr, &tmp_addr_sz) < 0)
41513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		goto err;
41613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
41713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	if (node_parse_addr(handle, addr, proto, tmp_addr) < 0)
41813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		goto err;
41913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
42013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	free(node->addr);
42113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	node->addr = tmp_addr;
42213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	node->addr_sz = tmp_addr_sz;
42313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	return STATUS_SUCCESS;
42413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
42513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle      err:
42613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	free(tmp_addr);
42713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	ERR(handle, "could not set node address to %s", addr);
42813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	return STATUS_ERR;
42913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle}
43013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
43113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindlehidden_def(sepol_node_set_addr)
43213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
43313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindleint sepol_node_set_addr_bytes(sepol_handle_t * handle,
43413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle			      sepol_node_t * node,
43513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle			      const char *addr, size_t addr_sz)
43613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{
43713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
43813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	char *tmp_addr = malloc(addr_sz);
43913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	if (!tmp_addr) {
44013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		ERR(handle, "out of memory, could not " "set node address");
44113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		return STATUS_ERR;
44213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	}
44313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
44413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	memcpy(tmp_addr, addr, addr_sz);
44513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	free(node->addr);
44613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	node->addr = tmp_addr;
44713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	node->addr_sz = addr_sz;
44813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	return STATUS_SUCCESS;
44913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle}
45013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
45113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindlehidden_def(sepol_node_set_addr_bytes)
45213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
45313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle/* Mask */
45413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindleint sepol_node_get_mask(sepol_handle_t * handle,
45513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle			const sepol_node_t * node, char **mask)
45613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{
45713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
45813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	char *tmp_mask = NULL;
45913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
46013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	if (node_alloc_addr_string(handle, node->proto, &tmp_mask) < 0)
46113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		goto err;
46213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
46313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	if (node_expand_addr(handle, node->mask, node->proto, tmp_mask) < 0)
46413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		goto err;
46513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
46613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	*mask = tmp_mask;
46713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	return STATUS_SUCCESS;
46813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
46913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle      err:
47013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	free(tmp_mask);
47113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	ERR(handle, "could not get node netmask");
47213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	return STATUS_ERR;
47313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle}
47413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
47513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindlehidden_def(sepol_node_get_mask)
47613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
47713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindleint sepol_node_get_mask_bytes(sepol_handle_t * handle,
47813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle			      const sepol_node_t * node,
47913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle			      char **buffer, size_t * bsize)
48013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{
48113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
48213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	char *tmp_buf = malloc(node->mask_sz);
48313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	if (!tmp_buf) {
48413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		ERR(handle, "out of memory, could not get netmask bytes");
48513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		return STATUS_ERR;
48613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	}
48713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
48813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	memcpy(tmp_buf, node->mask, node->mask_sz);
48913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	*buffer = tmp_buf;
49013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	*bsize = node->mask_sz;
49113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	return STATUS_SUCCESS;
49213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle}
49313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
49413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindlehidden_def(sepol_node_get_mask_bytes)
49513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
49613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindleint sepol_node_set_mask(sepol_handle_t * handle,
49713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle			sepol_node_t * node, int proto, const char *mask)
49813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{
49913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
50013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	char *tmp_mask = NULL;
50113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	size_t tmp_mask_sz;
50213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
50313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	if (node_alloc_addr(handle, proto, &tmp_mask, &tmp_mask_sz) < 0)
50413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		goto err;
50513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
50613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	if (node_parse_addr(handle, mask, proto, tmp_mask) < 0)
50713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		goto err;
50813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
50913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	free(node->mask);
51013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	node->mask = tmp_mask;
51113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	node->mask_sz = tmp_mask_sz;
51213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	return STATUS_SUCCESS;
51313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
51413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle      err:
51513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	free(tmp_mask);
51613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	ERR(handle, "could not set node netmask to %s", mask);
51713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	return STATUS_ERR;
51813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle}
51913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
52013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindlehidden_def(sepol_node_set_mask)
52113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
52213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindleint sepol_node_set_mask_bytes(sepol_handle_t * handle,
52313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle			      sepol_node_t * node,
52413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle			      const char *mask, size_t mask_sz)
52513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{
52613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
52713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	char *tmp_mask = malloc(mask_sz);
52813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	if (!tmp_mask) {
52913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		ERR(handle, "out of memory, could not " "set node netmask");
53013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		return STATUS_ERR;
53113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	}
53213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	memcpy(tmp_mask, mask, mask_sz);
53313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	free(node->mask);
53413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	node->mask = tmp_mask;
53513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	node->mask_sz = mask_sz;
53613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	return STATUS_SUCCESS;
53713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle}
53813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
53913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindlehidden_def(sepol_node_set_mask_bytes)
54013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
54113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle/* Protocol */
54213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindleint sepol_node_get_proto(const sepol_node_t * node)
54313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{
54413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
54513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	return node->proto;
54613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle}
54713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
54813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindlehidden_def(sepol_node_get_proto)
54913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
55013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindlevoid sepol_node_set_proto(sepol_node_t * node, int proto)
55113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{
55213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
55313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	node->proto = proto;
55413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle}
55513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
55613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindlehidden_def(sepol_node_set_proto)
55713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
55813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindleconst char *sepol_node_get_proto_str(int proto)
55913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{
56013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
56113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	switch (proto) {
56213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	case SEPOL_PROTO_IP4:
56313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		return "ipv4";
56413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	case SEPOL_PROTO_IP6:
56513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		return "ipv6";
56613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	default:
56713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		return "???";
56813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	}
56913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle}
57013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
57113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindlehidden_def(sepol_node_get_proto_str)
57213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
57313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle/* Create */
57413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindleint sepol_node_create(sepol_handle_t * handle, sepol_node_t ** node)
57513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{
57613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
57713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	sepol_node_t *tmp_node = (sepol_node_t *) malloc(sizeof(sepol_node_t));
57813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
57913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	if (!tmp_node) {
58013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		ERR(handle, "out of memory, could not create " "node record");
58113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		return STATUS_ERR;
58213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	}
58313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
58413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	tmp_node->addr = NULL;
58513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	tmp_node->addr_sz = 0;
58613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	tmp_node->mask = NULL;
58713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	tmp_node->mask_sz = 0;
58813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	tmp_node->proto = SEPOL_PROTO_IP4;
58913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	tmp_node->con = NULL;
59013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	*node = tmp_node;
59113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
59213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	return STATUS_SUCCESS;
59313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle}
59413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
59513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindlehidden_def(sepol_node_create)
59613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
59713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle/* Deep copy clone */
59813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindleint sepol_node_clone(sepol_handle_t * handle,
59913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		     const sepol_node_t * node, sepol_node_t ** node_ptr)
60013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{
60113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
60213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	sepol_node_t *new_node = NULL;
60313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	if (sepol_node_create(handle, &new_node) < 0)
60413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		goto err;
60513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
60613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	/* Copy address, mask, protocol */
60713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	new_node->addr = malloc(node->addr_sz);
60813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	new_node->mask = malloc(node->mask_sz);
60913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	if (!new_node->addr || !new_node->mask)
61013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		goto omem;
61113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
61213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	memcpy(new_node->addr, node->addr, node->addr_sz);
61313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	memcpy(new_node->mask, node->mask, node->mask_sz);
61413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	new_node->addr_sz = node->addr_sz;
61513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	new_node->mask_sz = node->mask_sz;
61613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	new_node->proto = node->proto;
61713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
61813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	/* Copy context */
61913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	if (node->con &&
62013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	    (sepol_context_clone(handle, node->con, &new_node->con) < 0))
62113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		goto err;
62213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
62313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	*node_ptr = new_node;
62413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	return STATUS_SUCCESS;
62513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
62613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle      omem:
62713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	ERR(handle, "out of memory");
62813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
62913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle      err:
63013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	ERR(handle, "could not clone node record");
63113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	sepol_node_free(new_node);
63213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	return STATUS_ERR;
63313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle}
63413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
63513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle/* Destroy */
63613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindlevoid sepol_node_free(sepol_node_t * node)
63713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{
63813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
63913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	if (!node)
64013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		return;
64113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
64213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	sepol_context_free(node->con);
64313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	free(node->addr);
64413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	free(node->mask);
64513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	free(node);
64613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle}
64713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
64813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindlehidden_def(sepol_node_free)
64913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
65013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle/* Context */
65113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindlesepol_context_t *sepol_node_get_con(const sepol_node_t * node)
65213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{
65313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
65413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	return node->con;
65513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle}
65613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
65713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindlehidden_def(sepol_node_get_con)
65813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
65913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindleint sepol_node_set_con(sepol_handle_t * handle,
66013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		       sepol_node_t * node, sepol_context_t * con)
66113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{
66213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
66313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	sepol_context_t *newcon;
66413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
66513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	if (sepol_context_clone(handle, con, &newcon) < 0) {
66613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		ERR(handle, "out of memory, could not set node context");
66713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		return STATUS_ERR;
66813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	}
66913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
67013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	sepol_context_free(node->con);
67113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	node->con = newcon;
67213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	return STATUS_SUCCESS;
67313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle}
67413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
67513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindlehidden_def(sepol_node_set_con)
676