1255e72915d4cbddceb435e13d81601755714e9fSE Android#include <stdlib.h>
2255e72915d4cbddceb435e13d81601755714e9fSE Android#include <stddef.h>
3255e72915d4cbddceb435e13d81601755714e9fSE Android#include <string.h>
4255e72915d4cbddceb435e13d81601755714e9fSE Android#include <netinet/in.h>
5255e72915d4cbddceb435e13d81601755714e9fSE Android#include <arpa/inet.h>
6255e72915d4cbddceb435e13d81601755714e9fSE Android#include <errno.h>
7255e72915d4cbddceb435e13d81601755714e9fSE Android
8255e72915d4cbddceb435e13d81601755714e9fSE Android#include "node_internal.h"
9255e72915d4cbddceb435e13d81601755714e9fSE Android#include "context_internal.h"
10255e72915d4cbddceb435e13d81601755714e9fSE Android#include "debug.h"
11255e72915d4cbddceb435e13d81601755714e9fSE Android
12255e72915d4cbddceb435e13d81601755714e9fSE Androidstruct sepol_node {
13255e72915d4cbddceb435e13d81601755714e9fSE Android
14255e72915d4cbddceb435e13d81601755714e9fSE Android	/* Network address and mask */
15255e72915d4cbddceb435e13d81601755714e9fSE Android	char *addr;
16255e72915d4cbddceb435e13d81601755714e9fSE Android	size_t addr_sz;
17255e72915d4cbddceb435e13d81601755714e9fSE Android
18255e72915d4cbddceb435e13d81601755714e9fSE Android	char *mask;
19255e72915d4cbddceb435e13d81601755714e9fSE Android	size_t mask_sz;
20255e72915d4cbddceb435e13d81601755714e9fSE Android
21255e72915d4cbddceb435e13d81601755714e9fSE Android	/* Protocol */
22255e72915d4cbddceb435e13d81601755714e9fSE Android	int proto;
23255e72915d4cbddceb435e13d81601755714e9fSE Android
24255e72915d4cbddceb435e13d81601755714e9fSE Android	/* Context */
25255e72915d4cbddceb435e13d81601755714e9fSE Android	sepol_context_t *con;
26255e72915d4cbddceb435e13d81601755714e9fSE Android};
27255e72915d4cbddceb435e13d81601755714e9fSE Android
28255e72915d4cbddceb435e13d81601755714e9fSE Androidstruct sepol_node_key {
29255e72915d4cbddceb435e13d81601755714e9fSE Android
30255e72915d4cbddceb435e13d81601755714e9fSE Android	/* Network address and mask */
31255e72915d4cbddceb435e13d81601755714e9fSE Android	char *addr;
32255e72915d4cbddceb435e13d81601755714e9fSE Android	size_t addr_sz;
33255e72915d4cbddceb435e13d81601755714e9fSE Android
34255e72915d4cbddceb435e13d81601755714e9fSE Android	char *mask;
35255e72915d4cbddceb435e13d81601755714e9fSE Android	size_t mask_sz;
36255e72915d4cbddceb435e13d81601755714e9fSE Android
37255e72915d4cbddceb435e13d81601755714e9fSE Android	/* Protocol */
38255e72915d4cbddceb435e13d81601755714e9fSE Android	int proto;
39255e72915d4cbddceb435e13d81601755714e9fSE Android};
40255e72915d4cbddceb435e13d81601755714e9fSE Android
41255e72915d4cbddceb435e13d81601755714e9fSE Android/* Converts a string represtation (addr_str)
42255e72915d4cbddceb435e13d81601755714e9fSE Android * to a numeric representation (addr_bytes) */
43255e72915d4cbddceb435e13d81601755714e9fSE Android
44255e72915d4cbddceb435e13d81601755714e9fSE Androidstatic int node_parse_addr(sepol_handle_t * handle,
45255e72915d4cbddceb435e13d81601755714e9fSE Android			   const char *addr_str, int proto, char *addr_bytes)
46255e72915d4cbddceb435e13d81601755714e9fSE Android{
47255e72915d4cbddceb435e13d81601755714e9fSE Android
48255e72915d4cbddceb435e13d81601755714e9fSE Android	switch (proto) {
49255e72915d4cbddceb435e13d81601755714e9fSE Android
50255e72915d4cbddceb435e13d81601755714e9fSE Android	case SEPOL_PROTO_IP4:
51255e72915d4cbddceb435e13d81601755714e9fSE Android		{
52255e72915d4cbddceb435e13d81601755714e9fSE Android			struct in_addr in_addr;
53255e72915d4cbddceb435e13d81601755714e9fSE Android
54255e72915d4cbddceb435e13d81601755714e9fSE Android			if (inet_pton(AF_INET, addr_str, &in_addr) <= 0) {
55255e72915d4cbddceb435e13d81601755714e9fSE Android				ERR(handle, "could not parse IPv4 address "
56255e72915d4cbddceb435e13d81601755714e9fSE Android				    "%s: %s", addr_str, strerror(errno));
57255e72915d4cbddceb435e13d81601755714e9fSE Android				return STATUS_ERR;
58255e72915d4cbddceb435e13d81601755714e9fSE Android			}
59255e72915d4cbddceb435e13d81601755714e9fSE Android
60255e72915d4cbddceb435e13d81601755714e9fSE Android			memcpy(addr_bytes, &in_addr.s_addr, 4);
61255e72915d4cbddceb435e13d81601755714e9fSE Android			break;
62255e72915d4cbddceb435e13d81601755714e9fSE Android		}
63255e72915d4cbddceb435e13d81601755714e9fSE Android	case SEPOL_PROTO_IP6:
64255e72915d4cbddceb435e13d81601755714e9fSE Android		{
65255e72915d4cbddceb435e13d81601755714e9fSE Android			struct in6_addr in_addr;
66255e72915d4cbddceb435e13d81601755714e9fSE Android
67255e72915d4cbddceb435e13d81601755714e9fSE Android			if (inet_pton(AF_INET6, addr_str, &in_addr) <= 0) {
68255e72915d4cbddceb435e13d81601755714e9fSE Android				ERR(handle, "could not parse IPv6 address "
69255e72915d4cbddceb435e13d81601755714e9fSE Android				    "%s: %s", addr_str, strerror(errno));
70255e72915d4cbddceb435e13d81601755714e9fSE Android				return STATUS_ERR;
71255e72915d4cbddceb435e13d81601755714e9fSE Android			}
72255e72915d4cbddceb435e13d81601755714e9fSE Android
73b1db49d77789525ac1f4e73e978e35694f21ea1aStephen Smalley#ifdef DARWIN
74b1db49d77789525ac1f4e73e978e35694f21ea1aStephen Smalley			memcpy(addr_bytes, in_addr.s6_addr, 16);
75b1db49d77789525ac1f4e73e978e35694f21ea1aStephen Smalley#else
76255e72915d4cbddceb435e13d81601755714e9fSE Android			memcpy(addr_bytes, in_addr.s6_addr32, 16);
77b1db49d77789525ac1f4e73e978e35694f21ea1aStephen Smalley#endif
78255e72915d4cbddceb435e13d81601755714e9fSE Android			break;
79255e72915d4cbddceb435e13d81601755714e9fSE Android		}
80255e72915d4cbddceb435e13d81601755714e9fSE Android	default:
81255e72915d4cbddceb435e13d81601755714e9fSE Android		ERR(handle, "unsupported protocol %u, could not "
82255e72915d4cbddceb435e13d81601755714e9fSE Android		    "parse address", proto);
83255e72915d4cbddceb435e13d81601755714e9fSE Android		return STATUS_ERR;
84255e72915d4cbddceb435e13d81601755714e9fSE Android	}
85255e72915d4cbddceb435e13d81601755714e9fSE Android
86255e72915d4cbddceb435e13d81601755714e9fSE Android	return STATUS_SUCCESS;
87255e72915d4cbddceb435e13d81601755714e9fSE Android}
88255e72915d4cbddceb435e13d81601755714e9fSE Android
89255e72915d4cbddceb435e13d81601755714e9fSE Android/* Allocates a sufficiently large buffer (addr, addr_sz)
90255e72915d4cbddceb435e13d81601755714e9fSE Android * according the the protocol */
91255e72915d4cbddceb435e13d81601755714e9fSE Android
92255e72915d4cbddceb435e13d81601755714e9fSE Androidstatic int node_alloc_addr(sepol_handle_t * handle,
93255e72915d4cbddceb435e13d81601755714e9fSE Android			   int proto, char **addr, size_t * addr_sz)
94255e72915d4cbddceb435e13d81601755714e9fSE Android{
95255e72915d4cbddceb435e13d81601755714e9fSE Android
96255e72915d4cbddceb435e13d81601755714e9fSE Android	char *tmp_addr = NULL;
97255e72915d4cbddceb435e13d81601755714e9fSE Android	size_t tmp_addr_sz;
98255e72915d4cbddceb435e13d81601755714e9fSE Android
99255e72915d4cbddceb435e13d81601755714e9fSE Android	switch (proto) {
100255e72915d4cbddceb435e13d81601755714e9fSE Android
101255e72915d4cbddceb435e13d81601755714e9fSE Android	case SEPOL_PROTO_IP4:
102255e72915d4cbddceb435e13d81601755714e9fSE Android		tmp_addr_sz = 4;
103255e72915d4cbddceb435e13d81601755714e9fSE Android		tmp_addr = malloc(4);
104255e72915d4cbddceb435e13d81601755714e9fSE Android		if (!tmp_addr)
105255e72915d4cbddceb435e13d81601755714e9fSE Android			goto omem;
106255e72915d4cbddceb435e13d81601755714e9fSE Android		break;
107255e72915d4cbddceb435e13d81601755714e9fSE Android
108255e72915d4cbddceb435e13d81601755714e9fSE Android	case SEPOL_PROTO_IP6:
109255e72915d4cbddceb435e13d81601755714e9fSE Android		tmp_addr_sz = 16;
110255e72915d4cbddceb435e13d81601755714e9fSE Android		tmp_addr = malloc(16);
111255e72915d4cbddceb435e13d81601755714e9fSE Android		if (!tmp_addr)
112255e72915d4cbddceb435e13d81601755714e9fSE Android			goto omem;
113255e72915d4cbddceb435e13d81601755714e9fSE Android		break;
114255e72915d4cbddceb435e13d81601755714e9fSE Android
115255e72915d4cbddceb435e13d81601755714e9fSE Android	default:
116255e72915d4cbddceb435e13d81601755714e9fSE Android		ERR(handle, "unsupported protocol %u", proto);
117255e72915d4cbddceb435e13d81601755714e9fSE Android		goto err;
118255e72915d4cbddceb435e13d81601755714e9fSE Android	}
119255e72915d4cbddceb435e13d81601755714e9fSE Android
120255e72915d4cbddceb435e13d81601755714e9fSE Android	*addr = tmp_addr;
121255e72915d4cbddceb435e13d81601755714e9fSE Android	*addr_sz = tmp_addr_sz;
122255e72915d4cbddceb435e13d81601755714e9fSE Android	return STATUS_SUCCESS;
123255e72915d4cbddceb435e13d81601755714e9fSE Android
124255e72915d4cbddceb435e13d81601755714e9fSE Android      omem:
125255e72915d4cbddceb435e13d81601755714e9fSE Android	ERR(handle, "out of memory");
126255e72915d4cbddceb435e13d81601755714e9fSE Android
127255e72915d4cbddceb435e13d81601755714e9fSE Android      err:
128255e72915d4cbddceb435e13d81601755714e9fSE Android	free(tmp_addr);
129255e72915d4cbddceb435e13d81601755714e9fSE Android	ERR(handle, "could not allocate address of protocol %s",
130255e72915d4cbddceb435e13d81601755714e9fSE Android	    sepol_node_get_proto_str(proto));
131255e72915d4cbddceb435e13d81601755714e9fSE Android	return STATUS_ERR;
132255e72915d4cbddceb435e13d81601755714e9fSE Android}
133255e72915d4cbddceb435e13d81601755714e9fSE Android
134255e72915d4cbddceb435e13d81601755714e9fSE Android/* Converts a numeric representation (addr_bytes)
135255e72915d4cbddceb435e13d81601755714e9fSE Android * to a string representation (addr_str), according to
136255e72915d4cbddceb435e13d81601755714e9fSE Android * the protocol */
137255e72915d4cbddceb435e13d81601755714e9fSE Android
138255e72915d4cbddceb435e13d81601755714e9fSE Androidstatic int node_expand_addr(sepol_handle_t * handle,
139255e72915d4cbddceb435e13d81601755714e9fSE Android			    char *addr_bytes, int proto, char *addr_str)
140255e72915d4cbddceb435e13d81601755714e9fSE Android{
141255e72915d4cbddceb435e13d81601755714e9fSE Android
142255e72915d4cbddceb435e13d81601755714e9fSE Android	switch (proto) {
143255e72915d4cbddceb435e13d81601755714e9fSE Android
144255e72915d4cbddceb435e13d81601755714e9fSE Android	case SEPOL_PROTO_IP4:
145255e72915d4cbddceb435e13d81601755714e9fSE Android		{
146255e72915d4cbddceb435e13d81601755714e9fSE Android			struct in_addr addr;
147255e72915d4cbddceb435e13d81601755714e9fSE Android			memset(&addr, 0, sizeof(struct in_addr));
148255e72915d4cbddceb435e13d81601755714e9fSE Android			memcpy(&addr.s_addr, addr_bytes, 4);
149255e72915d4cbddceb435e13d81601755714e9fSE Android
150255e72915d4cbddceb435e13d81601755714e9fSE Android			if (inet_ntop(AF_INET, &addr, addr_str,
151255e72915d4cbddceb435e13d81601755714e9fSE Android				      INET_ADDRSTRLEN) == NULL) {
152255e72915d4cbddceb435e13d81601755714e9fSE Android
153255e72915d4cbddceb435e13d81601755714e9fSE Android				ERR(handle,
154255e72915d4cbddceb435e13d81601755714e9fSE Android				    "could not expand IPv4 address to string: %s",
155255e72915d4cbddceb435e13d81601755714e9fSE Android				    strerror(errno));
156255e72915d4cbddceb435e13d81601755714e9fSE Android				return STATUS_ERR;
157255e72915d4cbddceb435e13d81601755714e9fSE Android			}
158255e72915d4cbddceb435e13d81601755714e9fSE Android			break;
159255e72915d4cbddceb435e13d81601755714e9fSE Android		}
160255e72915d4cbddceb435e13d81601755714e9fSE Android
161255e72915d4cbddceb435e13d81601755714e9fSE Android	case SEPOL_PROTO_IP6:
162255e72915d4cbddceb435e13d81601755714e9fSE Android		{
163255e72915d4cbddceb435e13d81601755714e9fSE Android			struct in6_addr addr;
164255e72915d4cbddceb435e13d81601755714e9fSE Android			memset(&addr, 0, sizeof(struct in6_addr));
165b1db49d77789525ac1f4e73e978e35694f21ea1aStephen Smalley#ifdef DARWIN
166b1db49d77789525ac1f4e73e978e35694f21ea1aStephen Smalley			memcpy(&addr.s6_addr[0], addr_bytes, 16);
167b1db49d77789525ac1f4e73e978e35694f21ea1aStephen Smalley#else
168255e72915d4cbddceb435e13d81601755714e9fSE Android			memcpy(&addr.s6_addr32[0], addr_bytes, 16);
169b1db49d77789525ac1f4e73e978e35694f21ea1aStephen Smalley#endif
170255e72915d4cbddceb435e13d81601755714e9fSE Android			if (inet_ntop(AF_INET6, &addr, addr_str,
171255e72915d4cbddceb435e13d81601755714e9fSE Android				      INET6_ADDRSTRLEN) == NULL) {
172255e72915d4cbddceb435e13d81601755714e9fSE Android
173255e72915d4cbddceb435e13d81601755714e9fSE Android				ERR(handle,
174255e72915d4cbddceb435e13d81601755714e9fSE Android				    "could not expand IPv6 address to string: %s",
175255e72915d4cbddceb435e13d81601755714e9fSE Android				    strerror(errno));
176255e72915d4cbddceb435e13d81601755714e9fSE Android				return STATUS_ERR;
177255e72915d4cbddceb435e13d81601755714e9fSE Android			}
178255e72915d4cbddceb435e13d81601755714e9fSE Android			break;
179255e72915d4cbddceb435e13d81601755714e9fSE Android		}
180255e72915d4cbddceb435e13d81601755714e9fSE Android
181255e72915d4cbddceb435e13d81601755714e9fSE Android	default:
182255e72915d4cbddceb435e13d81601755714e9fSE Android		ERR(handle, "unsupported protocol %u, could not"
183255e72915d4cbddceb435e13d81601755714e9fSE Android		    " expand address to string", proto);
184255e72915d4cbddceb435e13d81601755714e9fSE Android		return STATUS_ERR;
185255e72915d4cbddceb435e13d81601755714e9fSE Android	}
186255e72915d4cbddceb435e13d81601755714e9fSE Android
187255e72915d4cbddceb435e13d81601755714e9fSE Android	return STATUS_SUCCESS;
188255e72915d4cbddceb435e13d81601755714e9fSE Android}
189255e72915d4cbddceb435e13d81601755714e9fSE Android
190255e72915d4cbddceb435e13d81601755714e9fSE Android/* Allocates a sufficiently large address string (addr)
191255e72915d4cbddceb435e13d81601755714e9fSE Android * according to the protocol */
192255e72915d4cbddceb435e13d81601755714e9fSE Android
193255e72915d4cbddceb435e13d81601755714e9fSE Androidstatic int node_alloc_addr_string(sepol_handle_t * handle,
194255e72915d4cbddceb435e13d81601755714e9fSE Android				  int proto, char **addr)
195255e72915d4cbddceb435e13d81601755714e9fSE Android{
196255e72915d4cbddceb435e13d81601755714e9fSE Android
197255e72915d4cbddceb435e13d81601755714e9fSE Android	char *tmp_addr = NULL;
198255e72915d4cbddceb435e13d81601755714e9fSE Android
199255e72915d4cbddceb435e13d81601755714e9fSE Android	switch (proto) {
200255e72915d4cbddceb435e13d81601755714e9fSE Android
201255e72915d4cbddceb435e13d81601755714e9fSE Android	case SEPOL_PROTO_IP4:
202255e72915d4cbddceb435e13d81601755714e9fSE Android		tmp_addr = malloc(INET_ADDRSTRLEN);
203255e72915d4cbddceb435e13d81601755714e9fSE Android		if (!tmp_addr)
204255e72915d4cbddceb435e13d81601755714e9fSE Android			goto omem;
205255e72915d4cbddceb435e13d81601755714e9fSE Android		break;
206255e72915d4cbddceb435e13d81601755714e9fSE Android
207255e72915d4cbddceb435e13d81601755714e9fSE Android	case SEPOL_PROTO_IP6:
208255e72915d4cbddceb435e13d81601755714e9fSE Android		tmp_addr = malloc(INET6_ADDRSTRLEN);
209255e72915d4cbddceb435e13d81601755714e9fSE Android		if (!tmp_addr)
210255e72915d4cbddceb435e13d81601755714e9fSE Android			goto omem;
211255e72915d4cbddceb435e13d81601755714e9fSE Android		break;
212255e72915d4cbddceb435e13d81601755714e9fSE Android
213255e72915d4cbddceb435e13d81601755714e9fSE Android	default:
214255e72915d4cbddceb435e13d81601755714e9fSE Android		ERR(handle, "unsupported protocol %u", proto);
215255e72915d4cbddceb435e13d81601755714e9fSE Android		goto err;
216255e72915d4cbddceb435e13d81601755714e9fSE Android	}
217255e72915d4cbddceb435e13d81601755714e9fSE Android
218255e72915d4cbddceb435e13d81601755714e9fSE Android	*addr = tmp_addr;
219255e72915d4cbddceb435e13d81601755714e9fSE Android	return STATUS_SUCCESS;
220255e72915d4cbddceb435e13d81601755714e9fSE Android
221255e72915d4cbddceb435e13d81601755714e9fSE Android      omem:
222255e72915d4cbddceb435e13d81601755714e9fSE Android	ERR(handle, "out of memory");
223255e72915d4cbddceb435e13d81601755714e9fSE Android
224255e72915d4cbddceb435e13d81601755714e9fSE Android      err:
225255e72915d4cbddceb435e13d81601755714e9fSE Android	free(tmp_addr);
226255e72915d4cbddceb435e13d81601755714e9fSE Android	ERR(handle, "could not allocate string buffer for "
227255e72915d4cbddceb435e13d81601755714e9fSE Android	    "address of protocol %s", sepol_node_get_proto_str(proto));
228255e72915d4cbddceb435e13d81601755714e9fSE Android	return STATUS_ERR;
229255e72915d4cbddceb435e13d81601755714e9fSE Android}
230255e72915d4cbddceb435e13d81601755714e9fSE Android
231255e72915d4cbddceb435e13d81601755714e9fSE Android/* Key */
232255e72915d4cbddceb435e13d81601755714e9fSE Androidint sepol_node_key_create(sepol_handle_t * handle,
233255e72915d4cbddceb435e13d81601755714e9fSE Android			  const char *addr,
234255e72915d4cbddceb435e13d81601755714e9fSE Android			  const char *mask,
235255e72915d4cbddceb435e13d81601755714e9fSE Android			  int proto, sepol_node_key_t ** key_ptr)
236255e72915d4cbddceb435e13d81601755714e9fSE Android{
237255e72915d4cbddceb435e13d81601755714e9fSE Android
238255e72915d4cbddceb435e13d81601755714e9fSE Android	sepol_node_key_t *tmp_key =
239255e72915d4cbddceb435e13d81601755714e9fSE Android	    (sepol_node_key_t *) calloc(1, sizeof(sepol_node_key_t));
240255e72915d4cbddceb435e13d81601755714e9fSE Android	if (!tmp_key)
241255e72915d4cbddceb435e13d81601755714e9fSE Android		goto omem;
242255e72915d4cbddceb435e13d81601755714e9fSE Android
243255e72915d4cbddceb435e13d81601755714e9fSE Android	if (node_alloc_addr(handle, proto, &tmp_key->addr, &tmp_key->addr_sz) <
244255e72915d4cbddceb435e13d81601755714e9fSE Android	    0)
245255e72915d4cbddceb435e13d81601755714e9fSE Android		goto err;
246255e72915d4cbddceb435e13d81601755714e9fSE Android	if (node_parse_addr(handle, addr, proto, tmp_key->addr) < 0)
247255e72915d4cbddceb435e13d81601755714e9fSE Android		goto err;
248255e72915d4cbddceb435e13d81601755714e9fSE Android
249255e72915d4cbddceb435e13d81601755714e9fSE Android	if (node_alloc_addr(handle, proto, &tmp_key->mask, &tmp_key->mask_sz) <
250255e72915d4cbddceb435e13d81601755714e9fSE Android	    0)
251255e72915d4cbddceb435e13d81601755714e9fSE Android		goto err;
252255e72915d4cbddceb435e13d81601755714e9fSE Android	if (node_parse_addr(handle, mask, proto, tmp_key->mask) < 0)
253255e72915d4cbddceb435e13d81601755714e9fSE Android		goto err;
254255e72915d4cbddceb435e13d81601755714e9fSE Android
255255e72915d4cbddceb435e13d81601755714e9fSE Android	tmp_key->proto = proto;
256255e72915d4cbddceb435e13d81601755714e9fSE Android
257255e72915d4cbddceb435e13d81601755714e9fSE Android	*key_ptr = tmp_key;
258255e72915d4cbddceb435e13d81601755714e9fSE Android	return STATUS_SUCCESS;
259255e72915d4cbddceb435e13d81601755714e9fSE Android
260255e72915d4cbddceb435e13d81601755714e9fSE Android      omem:
261255e72915d4cbddceb435e13d81601755714e9fSE Android	ERR(handle, "out of memory");
262255e72915d4cbddceb435e13d81601755714e9fSE Android
263255e72915d4cbddceb435e13d81601755714e9fSE Android      err:
264255e72915d4cbddceb435e13d81601755714e9fSE Android	sepol_node_key_free(tmp_key);
265255e72915d4cbddceb435e13d81601755714e9fSE Android	ERR(handle, "could not create node key for (%s, %s, %s)",
266255e72915d4cbddceb435e13d81601755714e9fSE Android	    addr, mask, sepol_node_get_proto_str(proto));
267255e72915d4cbddceb435e13d81601755714e9fSE Android	return STATUS_ERR;
268255e72915d4cbddceb435e13d81601755714e9fSE Android}
269255e72915d4cbddceb435e13d81601755714e9fSE Android
270255e72915d4cbddceb435e13d81601755714e9fSE Androidhidden_def(sepol_node_key_create)
271255e72915d4cbddceb435e13d81601755714e9fSE Android
272255e72915d4cbddceb435e13d81601755714e9fSE Androidvoid sepol_node_key_unpack(const sepol_node_key_t * key,
273255e72915d4cbddceb435e13d81601755714e9fSE Android			   const char **addr, const char **mask, int *proto)
274255e72915d4cbddceb435e13d81601755714e9fSE Android{
275255e72915d4cbddceb435e13d81601755714e9fSE Android
276255e72915d4cbddceb435e13d81601755714e9fSE Android	*addr = key->addr;
277255e72915d4cbddceb435e13d81601755714e9fSE Android	*mask = key->mask;
278255e72915d4cbddceb435e13d81601755714e9fSE Android	*proto = key->proto;
279255e72915d4cbddceb435e13d81601755714e9fSE Android}
280255e72915d4cbddceb435e13d81601755714e9fSE Android
281255e72915d4cbddceb435e13d81601755714e9fSE Androidhidden_def(sepol_node_key_unpack)
282255e72915d4cbddceb435e13d81601755714e9fSE Android
283255e72915d4cbddceb435e13d81601755714e9fSE Androidint sepol_node_key_extract(sepol_handle_t * handle,
284255e72915d4cbddceb435e13d81601755714e9fSE Android			   const sepol_node_t * node,
285255e72915d4cbddceb435e13d81601755714e9fSE Android			   sepol_node_key_t ** key_ptr)
286255e72915d4cbddceb435e13d81601755714e9fSE Android{
287255e72915d4cbddceb435e13d81601755714e9fSE Android
288255e72915d4cbddceb435e13d81601755714e9fSE Android	sepol_node_key_t *tmp_key =
289255e72915d4cbddceb435e13d81601755714e9fSE Android	    (sepol_node_key_t *) calloc(1, sizeof(sepol_node_key_t));
290255e72915d4cbddceb435e13d81601755714e9fSE Android	if (!tmp_key)
291255e72915d4cbddceb435e13d81601755714e9fSE Android		goto omem;
292255e72915d4cbddceb435e13d81601755714e9fSE Android
293255e72915d4cbddceb435e13d81601755714e9fSE Android	tmp_key->addr = malloc(node->addr_sz);
294255e72915d4cbddceb435e13d81601755714e9fSE Android	tmp_key->mask = malloc(node->mask_sz);
295255e72915d4cbddceb435e13d81601755714e9fSE Android
296255e72915d4cbddceb435e13d81601755714e9fSE Android	if (!tmp_key->addr || !tmp_key->mask)
297255e72915d4cbddceb435e13d81601755714e9fSE Android		goto omem;
298255e72915d4cbddceb435e13d81601755714e9fSE Android
299255e72915d4cbddceb435e13d81601755714e9fSE Android	memcpy(tmp_key->addr, node->addr, node->addr_sz);
300255e72915d4cbddceb435e13d81601755714e9fSE Android	memcpy(tmp_key->mask, node->mask, node->mask_sz);
301255e72915d4cbddceb435e13d81601755714e9fSE Android	tmp_key->addr_sz = node->addr_sz;
302255e72915d4cbddceb435e13d81601755714e9fSE Android	tmp_key->mask_sz = node->mask_sz;
303255e72915d4cbddceb435e13d81601755714e9fSE Android	tmp_key->proto = node->proto;
304255e72915d4cbddceb435e13d81601755714e9fSE Android
305255e72915d4cbddceb435e13d81601755714e9fSE Android	*key_ptr = tmp_key;
306255e72915d4cbddceb435e13d81601755714e9fSE Android	return STATUS_SUCCESS;
307255e72915d4cbddceb435e13d81601755714e9fSE Android
308255e72915d4cbddceb435e13d81601755714e9fSE Android      omem:
309255e72915d4cbddceb435e13d81601755714e9fSE Android	sepol_node_key_free(tmp_key);
310255e72915d4cbddceb435e13d81601755714e9fSE Android	ERR(handle, "out of memory, could not extract node key");
311255e72915d4cbddceb435e13d81601755714e9fSE Android	return STATUS_ERR;
312255e72915d4cbddceb435e13d81601755714e9fSE Android}
313255e72915d4cbddceb435e13d81601755714e9fSE Android
314255e72915d4cbddceb435e13d81601755714e9fSE Androidvoid sepol_node_key_free(sepol_node_key_t * key)
315255e72915d4cbddceb435e13d81601755714e9fSE Android{
316255e72915d4cbddceb435e13d81601755714e9fSE Android
317255e72915d4cbddceb435e13d81601755714e9fSE Android	if (!key)
318255e72915d4cbddceb435e13d81601755714e9fSE Android		return;
319255e72915d4cbddceb435e13d81601755714e9fSE Android
320255e72915d4cbddceb435e13d81601755714e9fSE Android	free(key->addr);
321255e72915d4cbddceb435e13d81601755714e9fSE Android	free(key->mask);
322255e72915d4cbddceb435e13d81601755714e9fSE Android	free(key);
323255e72915d4cbddceb435e13d81601755714e9fSE Android}
324255e72915d4cbddceb435e13d81601755714e9fSE Android
325255e72915d4cbddceb435e13d81601755714e9fSE Androidhidden_def(sepol_node_key_free)
326255e72915d4cbddceb435e13d81601755714e9fSE Android
327255e72915d4cbddceb435e13d81601755714e9fSE Androidint sepol_node_compare(const sepol_node_t * node, const sepol_node_key_t * key)
328255e72915d4cbddceb435e13d81601755714e9fSE Android{
329255e72915d4cbddceb435e13d81601755714e9fSE Android
330255e72915d4cbddceb435e13d81601755714e9fSE Android	int rc1, rc2;
331255e72915d4cbddceb435e13d81601755714e9fSE Android
332255e72915d4cbddceb435e13d81601755714e9fSE Android	if ((node->addr_sz < key->addr_sz) || (node->mask_sz < key->mask_sz))
333255e72915d4cbddceb435e13d81601755714e9fSE Android		return -1;
334255e72915d4cbddceb435e13d81601755714e9fSE Android
335255e72915d4cbddceb435e13d81601755714e9fSE Android	else if ((node->addr_sz > key->addr_sz) ||
336255e72915d4cbddceb435e13d81601755714e9fSE Android		 (node->mask_sz > key->mask_sz))
337255e72915d4cbddceb435e13d81601755714e9fSE Android		return 1;
338255e72915d4cbddceb435e13d81601755714e9fSE Android
339255e72915d4cbddceb435e13d81601755714e9fSE Android	rc1 = memcmp(node->addr, key->addr, node->addr_sz);
340255e72915d4cbddceb435e13d81601755714e9fSE Android	rc2 = memcmp(node->mask, key->mask, node->mask_sz);
341255e72915d4cbddceb435e13d81601755714e9fSE Android
342255e72915d4cbddceb435e13d81601755714e9fSE Android	return (rc2 != 0) ? rc2 : rc1;
343255e72915d4cbddceb435e13d81601755714e9fSE Android}
344255e72915d4cbddceb435e13d81601755714e9fSE Android
345255e72915d4cbddceb435e13d81601755714e9fSE Androidint sepol_node_compare2(const sepol_node_t * node, const sepol_node_t * node2)
346255e72915d4cbddceb435e13d81601755714e9fSE Android{
347255e72915d4cbddceb435e13d81601755714e9fSE Android
348255e72915d4cbddceb435e13d81601755714e9fSE Android	int rc1, rc2;
349255e72915d4cbddceb435e13d81601755714e9fSE Android
350255e72915d4cbddceb435e13d81601755714e9fSE Android	if ((node->addr_sz < node2->addr_sz) ||
351255e72915d4cbddceb435e13d81601755714e9fSE Android	    (node->mask_sz < node2->mask_sz))
352255e72915d4cbddceb435e13d81601755714e9fSE Android		return -1;
353255e72915d4cbddceb435e13d81601755714e9fSE Android
354255e72915d4cbddceb435e13d81601755714e9fSE Android	else if ((node->addr_sz > node2->addr_sz) ||
355255e72915d4cbddceb435e13d81601755714e9fSE Android		 (node->mask_sz > node2->mask_sz))
356255e72915d4cbddceb435e13d81601755714e9fSE Android		return 1;
357255e72915d4cbddceb435e13d81601755714e9fSE Android
358255e72915d4cbddceb435e13d81601755714e9fSE Android	rc1 = memcmp(node->addr, node2->addr, node->addr_sz);
359255e72915d4cbddceb435e13d81601755714e9fSE Android	rc2 = memcmp(node->mask, node2->mask, node->mask_sz);
360255e72915d4cbddceb435e13d81601755714e9fSE Android
361255e72915d4cbddceb435e13d81601755714e9fSE Android	return (rc2 != 0) ? rc2 : rc1;
362255e72915d4cbddceb435e13d81601755714e9fSE Android}
363255e72915d4cbddceb435e13d81601755714e9fSE Android
364255e72915d4cbddceb435e13d81601755714e9fSE Android/* Addr */
365255e72915d4cbddceb435e13d81601755714e9fSE Androidint sepol_node_get_addr(sepol_handle_t * handle,
366255e72915d4cbddceb435e13d81601755714e9fSE Android			const sepol_node_t * node, char **addr)
367255e72915d4cbddceb435e13d81601755714e9fSE Android{
368255e72915d4cbddceb435e13d81601755714e9fSE Android
369255e72915d4cbddceb435e13d81601755714e9fSE Android	char *tmp_addr = NULL;
370255e72915d4cbddceb435e13d81601755714e9fSE Android
371255e72915d4cbddceb435e13d81601755714e9fSE Android	if (node_alloc_addr_string(handle, node->proto, &tmp_addr) < 0)
372255e72915d4cbddceb435e13d81601755714e9fSE Android		goto err;
373255e72915d4cbddceb435e13d81601755714e9fSE Android
374255e72915d4cbddceb435e13d81601755714e9fSE Android	if (node_expand_addr(handle, node->addr, node->proto, tmp_addr) < 0)
375255e72915d4cbddceb435e13d81601755714e9fSE Android		goto err;
376255e72915d4cbddceb435e13d81601755714e9fSE Android
377255e72915d4cbddceb435e13d81601755714e9fSE Android	*addr = tmp_addr;
378255e72915d4cbddceb435e13d81601755714e9fSE Android	return STATUS_SUCCESS;
379255e72915d4cbddceb435e13d81601755714e9fSE Android
380255e72915d4cbddceb435e13d81601755714e9fSE Android      err:
381255e72915d4cbddceb435e13d81601755714e9fSE Android	free(tmp_addr);
382255e72915d4cbddceb435e13d81601755714e9fSE Android	ERR(handle, "could not get node address");
383255e72915d4cbddceb435e13d81601755714e9fSE Android	return STATUS_ERR;
384255e72915d4cbddceb435e13d81601755714e9fSE Android}
385255e72915d4cbddceb435e13d81601755714e9fSE Android
386255e72915d4cbddceb435e13d81601755714e9fSE Androidhidden_def(sepol_node_get_addr)
387255e72915d4cbddceb435e13d81601755714e9fSE Android
388255e72915d4cbddceb435e13d81601755714e9fSE Androidint sepol_node_get_addr_bytes(sepol_handle_t * handle,
389255e72915d4cbddceb435e13d81601755714e9fSE Android			      const sepol_node_t * node,
390255e72915d4cbddceb435e13d81601755714e9fSE Android			      char **buffer, size_t * bsize)
391255e72915d4cbddceb435e13d81601755714e9fSE Android{
392255e72915d4cbddceb435e13d81601755714e9fSE Android
393255e72915d4cbddceb435e13d81601755714e9fSE Android	char *tmp_buf = malloc(node->addr_sz);
394255e72915d4cbddceb435e13d81601755714e9fSE Android	if (!tmp_buf) {
395255e72915d4cbddceb435e13d81601755714e9fSE Android		ERR(handle, "out of memory, could not get address bytes");
396255e72915d4cbddceb435e13d81601755714e9fSE Android		return STATUS_ERR;
397255e72915d4cbddceb435e13d81601755714e9fSE Android	}
398255e72915d4cbddceb435e13d81601755714e9fSE Android
399255e72915d4cbddceb435e13d81601755714e9fSE Android	memcpy(tmp_buf, node->addr, node->addr_sz);
400255e72915d4cbddceb435e13d81601755714e9fSE Android	*buffer = tmp_buf;
401255e72915d4cbddceb435e13d81601755714e9fSE Android	*bsize = node->addr_sz;
402255e72915d4cbddceb435e13d81601755714e9fSE Android	return STATUS_SUCCESS;
403255e72915d4cbddceb435e13d81601755714e9fSE Android}
404255e72915d4cbddceb435e13d81601755714e9fSE Android
405255e72915d4cbddceb435e13d81601755714e9fSE Androidhidden_def(sepol_node_get_addr_bytes)
406255e72915d4cbddceb435e13d81601755714e9fSE Android
407255e72915d4cbddceb435e13d81601755714e9fSE Androidint sepol_node_set_addr(sepol_handle_t * handle,
408255e72915d4cbddceb435e13d81601755714e9fSE Android			sepol_node_t * node, int proto, const char *addr)
409255e72915d4cbddceb435e13d81601755714e9fSE Android{
410255e72915d4cbddceb435e13d81601755714e9fSE Android
411255e72915d4cbddceb435e13d81601755714e9fSE Android	char *tmp_addr = NULL;
412255e72915d4cbddceb435e13d81601755714e9fSE Android	size_t tmp_addr_sz;
413255e72915d4cbddceb435e13d81601755714e9fSE Android
414255e72915d4cbddceb435e13d81601755714e9fSE Android	if (node_alloc_addr(handle, proto, &tmp_addr, &tmp_addr_sz) < 0)
415255e72915d4cbddceb435e13d81601755714e9fSE Android		goto err;
416255e72915d4cbddceb435e13d81601755714e9fSE Android
417255e72915d4cbddceb435e13d81601755714e9fSE Android	if (node_parse_addr(handle, addr, proto, tmp_addr) < 0)
418255e72915d4cbddceb435e13d81601755714e9fSE Android		goto err;
419255e72915d4cbddceb435e13d81601755714e9fSE Android
420255e72915d4cbddceb435e13d81601755714e9fSE Android	free(node->addr);
421255e72915d4cbddceb435e13d81601755714e9fSE Android	node->addr = tmp_addr;
422255e72915d4cbddceb435e13d81601755714e9fSE Android	node->addr_sz = tmp_addr_sz;
423255e72915d4cbddceb435e13d81601755714e9fSE Android	return STATUS_SUCCESS;
424255e72915d4cbddceb435e13d81601755714e9fSE Android
425255e72915d4cbddceb435e13d81601755714e9fSE Android      err:
426255e72915d4cbddceb435e13d81601755714e9fSE Android	free(tmp_addr);
427255e72915d4cbddceb435e13d81601755714e9fSE Android	ERR(handle, "could not set node address to %s", addr);
428255e72915d4cbddceb435e13d81601755714e9fSE Android	return STATUS_ERR;
429255e72915d4cbddceb435e13d81601755714e9fSE Android}
430255e72915d4cbddceb435e13d81601755714e9fSE Android
431255e72915d4cbddceb435e13d81601755714e9fSE Androidhidden_def(sepol_node_set_addr)
432255e72915d4cbddceb435e13d81601755714e9fSE Android
433255e72915d4cbddceb435e13d81601755714e9fSE Androidint sepol_node_set_addr_bytes(sepol_handle_t * handle,
434255e72915d4cbddceb435e13d81601755714e9fSE Android			      sepol_node_t * node,
435255e72915d4cbddceb435e13d81601755714e9fSE Android			      const char *addr, size_t addr_sz)
436255e72915d4cbddceb435e13d81601755714e9fSE Android{
437255e72915d4cbddceb435e13d81601755714e9fSE Android
438255e72915d4cbddceb435e13d81601755714e9fSE Android	char *tmp_addr = malloc(addr_sz);
439255e72915d4cbddceb435e13d81601755714e9fSE Android	if (!tmp_addr) {
440255e72915d4cbddceb435e13d81601755714e9fSE Android		ERR(handle, "out of memory, could not " "set node address");
441255e72915d4cbddceb435e13d81601755714e9fSE Android		return STATUS_ERR;
442255e72915d4cbddceb435e13d81601755714e9fSE Android	}
443255e72915d4cbddceb435e13d81601755714e9fSE Android
444255e72915d4cbddceb435e13d81601755714e9fSE Android	memcpy(tmp_addr, addr, addr_sz);
445255e72915d4cbddceb435e13d81601755714e9fSE Android	free(node->addr);
446255e72915d4cbddceb435e13d81601755714e9fSE Android	node->addr = tmp_addr;
447255e72915d4cbddceb435e13d81601755714e9fSE Android	node->addr_sz = addr_sz;
448255e72915d4cbddceb435e13d81601755714e9fSE Android	return STATUS_SUCCESS;
449255e72915d4cbddceb435e13d81601755714e9fSE Android}
450255e72915d4cbddceb435e13d81601755714e9fSE Android
451255e72915d4cbddceb435e13d81601755714e9fSE Androidhidden_def(sepol_node_set_addr_bytes)
452255e72915d4cbddceb435e13d81601755714e9fSE Android
453255e72915d4cbddceb435e13d81601755714e9fSE Android/* Mask */
454255e72915d4cbddceb435e13d81601755714e9fSE Androidint sepol_node_get_mask(sepol_handle_t * handle,
455255e72915d4cbddceb435e13d81601755714e9fSE Android			const sepol_node_t * node, char **mask)
456255e72915d4cbddceb435e13d81601755714e9fSE Android{
457255e72915d4cbddceb435e13d81601755714e9fSE Android
458255e72915d4cbddceb435e13d81601755714e9fSE Android	char *tmp_mask = NULL;
459255e72915d4cbddceb435e13d81601755714e9fSE Android
460255e72915d4cbddceb435e13d81601755714e9fSE Android	if (node_alloc_addr_string(handle, node->proto, &tmp_mask) < 0)
461255e72915d4cbddceb435e13d81601755714e9fSE Android		goto err;
462255e72915d4cbddceb435e13d81601755714e9fSE Android
463255e72915d4cbddceb435e13d81601755714e9fSE Android	if (node_expand_addr(handle, node->mask, node->proto, tmp_mask) < 0)
464255e72915d4cbddceb435e13d81601755714e9fSE Android		goto err;
465255e72915d4cbddceb435e13d81601755714e9fSE Android
466255e72915d4cbddceb435e13d81601755714e9fSE Android	*mask = tmp_mask;
467255e72915d4cbddceb435e13d81601755714e9fSE Android	return STATUS_SUCCESS;
468255e72915d4cbddceb435e13d81601755714e9fSE Android
469255e72915d4cbddceb435e13d81601755714e9fSE Android      err:
470255e72915d4cbddceb435e13d81601755714e9fSE Android	free(tmp_mask);
471255e72915d4cbddceb435e13d81601755714e9fSE Android	ERR(handle, "could not get node netmask");
472255e72915d4cbddceb435e13d81601755714e9fSE Android	return STATUS_ERR;
473255e72915d4cbddceb435e13d81601755714e9fSE Android}
474255e72915d4cbddceb435e13d81601755714e9fSE Android
475255e72915d4cbddceb435e13d81601755714e9fSE Androidhidden_def(sepol_node_get_mask)
476255e72915d4cbddceb435e13d81601755714e9fSE Android
477255e72915d4cbddceb435e13d81601755714e9fSE Androidint sepol_node_get_mask_bytes(sepol_handle_t * handle,
478255e72915d4cbddceb435e13d81601755714e9fSE Android			      const sepol_node_t * node,
479255e72915d4cbddceb435e13d81601755714e9fSE Android			      char **buffer, size_t * bsize)
480255e72915d4cbddceb435e13d81601755714e9fSE Android{
481255e72915d4cbddceb435e13d81601755714e9fSE Android
482255e72915d4cbddceb435e13d81601755714e9fSE Android	char *tmp_buf = malloc(node->mask_sz);
483255e72915d4cbddceb435e13d81601755714e9fSE Android	if (!tmp_buf) {
484255e72915d4cbddceb435e13d81601755714e9fSE Android		ERR(handle, "out of memory, could not get netmask bytes");
485255e72915d4cbddceb435e13d81601755714e9fSE Android		return STATUS_ERR;
486255e72915d4cbddceb435e13d81601755714e9fSE Android	}
487255e72915d4cbddceb435e13d81601755714e9fSE Android
488255e72915d4cbddceb435e13d81601755714e9fSE Android	memcpy(tmp_buf, node->mask, node->mask_sz);
489255e72915d4cbddceb435e13d81601755714e9fSE Android	*buffer = tmp_buf;
490255e72915d4cbddceb435e13d81601755714e9fSE Android	*bsize = node->mask_sz;
491255e72915d4cbddceb435e13d81601755714e9fSE Android	return STATUS_SUCCESS;
492255e72915d4cbddceb435e13d81601755714e9fSE Android}
493255e72915d4cbddceb435e13d81601755714e9fSE Android
494255e72915d4cbddceb435e13d81601755714e9fSE Androidhidden_def(sepol_node_get_mask_bytes)
495255e72915d4cbddceb435e13d81601755714e9fSE Android
496255e72915d4cbddceb435e13d81601755714e9fSE Androidint sepol_node_set_mask(sepol_handle_t * handle,
497255e72915d4cbddceb435e13d81601755714e9fSE Android			sepol_node_t * node, int proto, const char *mask)
498255e72915d4cbddceb435e13d81601755714e9fSE Android{
499255e72915d4cbddceb435e13d81601755714e9fSE Android
500255e72915d4cbddceb435e13d81601755714e9fSE Android	char *tmp_mask = NULL;
501255e72915d4cbddceb435e13d81601755714e9fSE Android	size_t tmp_mask_sz;
502255e72915d4cbddceb435e13d81601755714e9fSE Android
503255e72915d4cbddceb435e13d81601755714e9fSE Android	if (node_alloc_addr(handle, proto, &tmp_mask, &tmp_mask_sz) < 0)
504255e72915d4cbddceb435e13d81601755714e9fSE Android		goto err;
505255e72915d4cbddceb435e13d81601755714e9fSE Android
506255e72915d4cbddceb435e13d81601755714e9fSE Android	if (node_parse_addr(handle, mask, proto, tmp_mask) < 0)
507255e72915d4cbddceb435e13d81601755714e9fSE Android		goto err;
508255e72915d4cbddceb435e13d81601755714e9fSE Android
509255e72915d4cbddceb435e13d81601755714e9fSE Android	free(node->mask);
510255e72915d4cbddceb435e13d81601755714e9fSE Android	node->mask = tmp_mask;
511255e72915d4cbddceb435e13d81601755714e9fSE Android	node->mask_sz = tmp_mask_sz;
512255e72915d4cbddceb435e13d81601755714e9fSE Android	return STATUS_SUCCESS;
513255e72915d4cbddceb435e13d81601755714e9fSE Android
514255e72915d4cbddceb435e13d81601755714e9fSE Android      err:
515255e72915d4cbddceb435e13d81601755714e9fSE Android	free(tmp_mask);
516255e72915d4cbddceb435e13d81601755714e9fSE Android	ERR(handle, "could not set node netmask to %s", mask);
517255e72915d4cbddceb435e13d81601755714e9fSE Android	return STATUS_ERR;
518255e72915d4cbddceb435e13d81601755714e9fSE Android}
519255e72915d4cbddceb435e13d81601755714e9fSE Android
520255e72915d4cbddceb435e13d81601755714e9fSE Androidhidden_def(sepol_node_set_mask)
521255e72915d4cbddceb435e13d81601755714e9fSE Android
522255e72915d4cbddceb435e13d81601755714e9fSE Androidint sepol_node_set_mask_bytes(sepol_handle_t * handle,
523255e72915d4cbddceb435e13d81601755714e9fSE Android			      sepol_node_t * node,
524255e72915d4cbddceb435e13d81601755714e9fSE Android			      const char *mask, size_t mask_sz)
525255e72915d4cbddceb435e13d81601755714e9fSE Android{
526255e72915d4cbddceb435e13d81601755714e9fSE Android
527255e72915d4cbddceb435e13d81601755714e9fSE Android	char *tmp_mask = malloc(mask_sz);
528255e72915d4cbddceb435e13d81601755714e9fSE Android	if (!tmp_mask) {
529255e72915d4cbddceb435e13d81601755714e9fSE Android		ERR(handle, "out of memory, could not " "set node netmask");
530255e72915d4cbddceb435e13d81601755714e9fSE Android		return STATUS_ERR;
531255e72915d4cbddceb435e13d81601755714e9fSE Android	}
532255e72915d4cbddceb435e13d81601755714e9fSE Android	memcpy(tmp_mask, mask, mask_sz);
533255e72915d4cbddceb435e13d81601755714e9fSE Android	free(node->mask);
534255e72915d4cbddceb435e13d81601755714e9fSE Android	node->mask = tmp_mask;
535255e72915d4cbddceb435e13d81601755714e9fSE Android	node->mask_sz = mask_sz;
536255e72915d4cbddceb435e13d81601755714e9fSE Android	return STATUS_SUCCESS;
537255e72915d4cbddceb435e13d81601755714e9fSE Android}
538255e72915d4cbddceb435e13d81601755714e9fSE Android
539255e72915d4cbddceb435e13d81601755714e9fSE Androidhidden_def(sepol_node_set_mask_bytes)
540255e72915d4cbddceb435e13d81601755714e9fSE Android
541255e72915d4cbddceb435e13d81601755714e9fSE Android/* Protocol */
542255e72915d4cbddceb435e13d81601755714e9fSE Androidint sepol_node_get_proto(const sepol_node_t * node)
543255e72915d4cbddceb435e13d81601755714e9fSE Android{
544255e72915d4cbddceb435e13d81601755714e9fSE Android
545255e72915d4cbddceb435e13d81601755714e9fSE Android	return node->proto;
546255e72915d4cbddceb435e13d81601755714e9fSE Android}
547255e72915d4cbddceb435e13d81601755714e9fSE Android
548255e72915d4cbddceb435e13d81601755714e9fSE Androidhidden_def(sepol_node_get_proto)
549255e72915d4cbddceb435e13d81601755714e9fSE Android
550255e72915d4cbddceb435e13d81601755714e9fSE Androidvoid sepol_node_set_proto(sepol_node_t * node, int proto)
551255e72915d4cbddceb435e13d81601755714e9fSE Android{
552255e72915d4cbddceb435e13d81601755714e9fSE Android
553255e72915d4cbddceb435e13d81601755714e9fSE Android	node->proto = proto;
554255e72915d4cbddceb435e13d81601755714e9fSE Android}
555255e72915d4cbddceb435e13d81601755714e9fSE Android
556255e72915d4cbddceb435e13d81601755714e9fSE Androidhidden_def(sepol_node_set_proto)
557255e72915d4cbddceb435e13d81601755714e9fSE Android
558255e72915d4cbddceb435e13d81601755714e9fSE Androidconst char *sepol_node_get_proto_str(int proto)
559255e72915d4cbddceb435e13d81601755714e9fSE Android{
560255e72915d4cbddceb435e13d81601755714e9fSE Android
561255e72915d4cbddceb435e13d81601755714e9fSE Android	switch (proto) {
562255e72915d4cbddceb435e13d81601755714e9fSE Android	case SEPOL_PROTO_IP4:
563255e72915d4cbddceb435e13d81601755714e9fSE Android		return "ipv4";
564255e72915d4cbddceb435e13d81601755714e9fSE Android	case SEPOL_PROTO_IP6:
565255e72915d4cbddceb435e13d81601755714e9fSE Android		return "ipv6";
566255e72915d4cbddceb435e13d81601755714e9fSE Android	default:
567255e72915d4cbddceb435e13d81601755714e9fSE Android		return "???";
568255e72915d4cbddceb435e13d81601755714e9fSE Android	}
569255e72915d4cbddceb435e13d81601755714e9fSE Android}
570255e72915d4cbddceb435e13d81601755714e9fSE Android
571255e72915d4cbddceb435e13d81601755714e9fSE Androidhidden_def(sepol_node_get_proto_str)
572255e72915d4cbddceb435e13d81601755714e9fSE Android
573255e72915d4cbddceb435e13d81601755714e9fSE Android/* Create */
574255e72915d4cbddceb435e13d81601755714e9fSE Androidint sepol_node_create(sepol_handle_t * handle, sepol_node_t ** node)
575255e72915d4cbddceb435e13d81601755714e9fSE Android{
576255e72915d4cbddceb435e13d81601755714e9fSE Android
577255e72915d4cbddceb435e13d81601755714e9fSE Android	sepol_node_t *tmp_node = (sepol_node_t *) malloc(sizeof(sepol_node_t));
578255e72915d4cbddceb435e13d81601755714e9fSE Android
579255e72915d4cbddceb435e13d81601755714e9fSE Android	if (!tmp_node) {
580255e72915d4cbddceb435e13d81601755714e9fSE Android		ERR(handle, "out of memory, could not create " "node record");
581255e72915d4cbddceb435e13d81601755714e9fSE Android		return STATUS_ERR;
582255e72915d4cbddceb435e13d81601755714e9fSE Android	}
583255e72915d4cbddceb435e13d81601755714e9fSE Android
584255e72915d4cbddceb435e13d81601755714e9fSE Android	tmp_node->addr = NULL;
585255e72915d4cbddceb435e13d81601755714e9fSE Android	tmp_node->addr_sz = 0;
586255e72915d4cbddceb435e13d81601755714e9fSE Android	tmp_node->mask = NULL;
587255e72915d4cbddceb435e13d81601755714e9fSE Android	tmp_node->mask_sz = 0;
588255e72915d4cbddceb435e13d81601755714e9fSE Android	tmp_node->proto = SEPOL_PROTO_IP4;
589255e72915d4cbddceb435e13d81601755714e9fSE Android	tmp_node->con = NULL;
590255e72915d4cbddceb435e13d81601755714e9fSE Android	*node = tmp_node;
591255e72915d4cbddceb435e13d81601755714e9fSE Android
592255e72915d4cbddceb435e13d81601755714e9fSE Android	return STATUS_SUCCESS;
593255e72915d4cbddceb435e13d81601755714e9fSE Android}
594255e72915d4cbddceb435e13d81601755714e9fSE Android
595255e72915d4cbddceb435e13d81601755714e9fSE Androidhidden_def(sepol_node_create)
596255e72915d4cbddceb435e13d81601755714e9fSE Android
597255e72915d4cbddceb435e13d81601755714e9fSE Android/* Deep copy clone */
598255e72915d4cbddceb435e13d81601755714e9fSE Androidint sepol_node_clone(sepol_handle_t * handle,
599255e72915d4cbddceb435e13d81601755714e9fSE Android		     const sepol_node_t * node, sepol_node_t ** node_ptr)
600255e72915d4cbddceb435e13d81601755714e9fSE Android{
601255e72915d4cbddceb435e13d81601755714e9fSE Android
602255e72915d4cbddceb435e13d81601755714e9fSE Android	sepol_node_t *new_node = NULL;
603255e72915d4cbddceb435e13d81601755714e9fSE Android	if (sepol_node_create(handle, &new_node) < 0)
604255e72915d4cbddceb435e13d81601755714e9fSE Android		goto err;
605255e72915d4cbddceb435e13d81601755714e9fSE Android
606255e72915d4cbddceb435e13d81601755714e9fSE Android	/* Copy address, mask, protocol */
607255e72915d4cbddceb435e13d81601755714e9fSE Android	new_node->addr = malloc(node->addr_sz);
608255e72915d4cbddceb435e13d81601755714e9fSE Android	new_node->mask = malloc(node->mask_sz);
609255e72915d4cbddceb435e13d81601755714e9fSE Android	if (!new_node->addr || !new_node->mask)
610255e72915d4cbddceb435e13d81601755714e9fSE Android		goto omem;
611255e72915d4cbddceb435e13d81601755714e9fSE Android
612255e72915d4cbddceb435e13d81601755714e9fSE Android	memcpy(new_node->addr, node->addr, node->addr_sz);
613255e72915d4cbddceb435e13d81601755714e9fSE Android	memcpy(new_node->mask, node->mask, node->mask_sz);
614255e72915d4cbddceb435e13d81601755714e9fSE Android	new_node->addr_sz = node->addr_sz;
615255e72915d4cbddceb435e13d81601755714e9fSE Android	new_node->mask_sz = node->mask_sz;
616255e72915d4cbddceb435e13d81601755714e9fSE Android	new_node->proto = node->proto;
617255e72915d4cbddceb435e13d81601755714e9fSE Android
618255e72915d4cbddceb435e13d81601755714e9fSE Android	/* Copy context */
619255e72915d4cbddceb435e13d81601755714e9fSE Android	if (node->con &&
620255e72915d4cbddceb435e13d81601755714e9fSE Android	    (sepol_context_clone(handle, node->con, &new_node->con) < 0))
621255e72915d4cbddceb435e13d81601755714e9fSE Android		goto err;
622255e72915d4cbddceb435e13d81601755714e9fSE Android
623255e72915d4cbddceb435e13d81601755714e9fSE Android	*node_ptr = new_node;
624255e72915d4cbddceb435e13d81601755714e9fSE Android	return STATUS_SUCCESS;
625255e72915d4cbddceb435e13d81601755714e9fSE Android
626255e72915d4cbddceb435e13d81601755714e9fSE Android      omem:
627255e72915d4cbddceb435e13d81601755714e9fSE Android	ERR(handle, "out of memory");
628255e72915d4cbddceb435e13d81601755714e9fSE Android
629255e72915d4cbddceb435e13d81601755714e9fSE Android      err:
630255e72915d4cbddceb435e13d81601755714e9fSE Android	ERR(handle, "could not clone node record");
631255e72915d4cbddceb435e13d81601755714e9fSE Android	sepol_node_free(new_node);
632255e72915d4cbddceb435e13d81601755714e9fSE Android	return STATUS_ERR;
633255e72915d4cbddceb435e13d81601755714e9fSE Android}
634255e72915d4cbddceb435e13d81601755714e9fSE Android
635255e72915d4cbddceb435e13d81601755714e9fSE Android/* Destroy */
636255e72915d4cbddceb435e13d81601755714e9fSE Androidvoid sepol_node_free(sepol_node_t * node)
637255e72915d4cbddceb435e13d81601755714e9fSE Android{
638255e72915d4cbddceb435e13d81601755714e9fSE Android
639255e72915d4cbddceb435e13d81601755714e9fSE Android	if (!node)
640255e72915d4cbddceb435e13d81601755714e9fSE Android		return;
641255e72915d4cbddceb435e13d81601755714e9fSE Android
642255e72915d4cbddceb435e13d81601755714e9fSE Android	sepol_context_free(node->con);
643255e72915d4cbddceb435e13d81601755714e9fSE Android	free(node->addr);
644255e72915d4cbddceb435e13d81601755714e9fSE Android	free(node->mask);
645255e72915d4cbddceb435e13d81601755714e9fSE Android	free(node);
646255e72915d4cbddceb435e13d81601755714e9fSE Android}
647255e72915d4cbddceb435e13d81601755714e9fSE Android
648255e72915d4cbddceb435e13d81601755714e9fSE Androidhidden_def(sepol_node_free)
649255e72915d4cbddceb435e13d81601755714e9fSE Android
650255e72915d4cbddceb435e13d81601755714e9fSE Android/* Context */
651255e72915d4cbddceb435e13d81601755714e9fSE Androidsepol_context_t *sepol_node_get_con(const sepol_node_t * node)
652255e72915d4cbddceb435e13d81601755714e9fSE Android{
653255e72915d4cbddceb435e13d81601755714e9fSE Android
654255e72915d4cbddceb435e13d81601755714e9fSE Android	return node->con;
655255e72915d4cbddceb435e13d81601755714e9fSE Android}
656255e72915d4cbddceb435e13d81601755714e9fSE Android
657255e72915d4cbddceb435e13d81601755714e9fSE Androidhidden_def(sepol_node_get_con)
658255e72915d4cbddceb435e13d81601755714e9fSE Android
659255e72915d4cbddceb435e13d81601755714e9fSE Androidint sepol_node_set_con(sepol_handle_t * handle,
660255e72915d4cbddceb435e13d81601755714e9fSE Android		       sepol_node_t * node, sepol_context_t * con)
661255e72915d4cbddceb435e13d81601755714e9fSE Android{
662255e72915d4cbddceb435e13d81601755714e9fSE Android
663255e72915d4cbddceb435e13d81601755714e9fSE Android	sepol_context_t *newcon;
664255e72915d4cbddceb435e13d81601755714e9fSE Android
665255e72915d4cbddceb435e13d81601755714e9fSE Android	if (sepol_context_clone(handle, con, &newcon) < 0) {
666255e72915d4cbddceb435e13d81601755714e9fSE Android		ERR(handle, "out of memory, could not set node context");
667255e72915d4cbddceb435e13d81601755714e9fSE Android		return STATUS_ERR;
668255e72915d4cbddceb435e13d81601755714e9fSE Android	}
669255e72915d4cbddceb435e13d81601755714e9fSE Android
670255e72915d4cbddceb435e13d81601755714e9fSE Android	sepol_context_free(node->con);
671255e72915d4cbddceb435e13d81601755714e9fSE Android	node->con = newcon;
672255e72915d4cbddceb435e13d81601755714e9fSE Android	return STATUS_SUCCESS;
673255e72915d4cbddceb435e13d81601755714e9fSE Android}
674255e72915d4cbddceb435e13d81601755714e9fSE Android
675255e72915d4cbddceb435e13d81601755714e9fSE Androidhidden_def(sepol_node_set_con)
676