1255e72915d4cbddceb435e13d81601755714e9fSE Android#include <stdlib.h>
2255e72915d4cbddceb435e13d81601755714e9fSE Android#include <string.h>
3255e72915d4cbddceb435e13d81601755714e9fSE Android
4255e72915d4cbddceb435e13d81601755714e9fSE Android#include "iface_internal.h"
5255e72915d4cbddceb435e13d81601755714e9fSE Android#include "context_internal.h"
6255e72915d4cbddceb435e13d81601755714e9fSE Android#include "debug.h"
7255e72915d4cbddceb435e13d81601755714e9fSE Android
8255e72915d4cbddceb435e13d81601755714e9fSE Androidstruct sepol_iface {
9255e72915d4cbddceb435e13d81601755714e9fSE Android
10255e72915d4cbddceb435e13d81601755714e9fSE Android	/* Interface name */
11255e72915d4cbddceb435e13d81601755714e9fSE Android	char *name;
12255e72915d4cbddceb435e13d81601755714e9fSE Android
13255e72915d4cbddceb435e13d81601755714e9fSE Android	/* Interface context */
14255e72915d4cbddceb435e13d81601755714e9fSE Android	sepol_context_t *netif_con;
15255e72915d4cbddceb435e13d81601755714e9fSE Android
16255e72915d4cbddceb435e13d81601755714e9fSE Android	/* Message context */
17255e72915d4cbddceb435e13d81601755714e9fSE Android	sepol_context_t *netmsg_con;
18255e72915d4cbddceb435e13d81601755714e9fSE Android};
19255e72915d4cbddceb435e13d81601755714e9fSE Android
20255e72915d4cbddceb435e13d81601755714e9fSE Androidstruct sepol_iface_key {
21255e72915d4cbddceb435e13d81601755714e9fSE Android
22255e72915d4cbddceb435e13d81601755714e9fSE Android	/* Interface name */
23255e72915d4cbddceb435e13d81601755714e9fSE Android	const char *name;
24255e72915d4cbddceb435e13d81601755714e9fSE Android};
25255e72915d4cbddceb435e13d81601755714e9fSE Android
26255e72915d4cbddceb435e13d81601755714e9fSE Android/* Key */
27255e72915d4cbddceb435e13d81601755714e9fSE Androidint sepol_iface_key_create(sepol_handle_t * handle,
28255e72915d4cbddceb435e13d81601755714e9fSE Android			   const char *name, sepol_iface_key_t ** key_ptr)
29255e72915d4cbddceb435e13d81601755714e9fSE Android{
30255e72915d4cbddceb435e13d81601755714e9fSE Android
31255e72915d4cbddceb435e13d81601755714e9fSE Android	sepol_iface_key_t *tmp_key =
32255e72915d4cbddceb435e13d81601755714e9fSE Android	    (sepol_iface_key_t *) malloc(sizeof(sepol_iface_key_t));
33255e72915d4cbddceb435e13d81601755714e9fSE Android
34255e72915d4cbddceb435e13d81601755714e9fSE Android	if (!tmp_key) {
35255e72915d4cbddceb435e13d81601755714e9fSE Android		ERR(handle, "out of memory, could not create interface key");
36255e72915d4cbddceb435e13d81601755714e9fSE Android		return STATUS_ERR;
37255e72915d4cbddceb435e13d81601755714e9fSE Android	}
38255e72915d4cbddceb435e13d81601755714e9fSE Android
39255e72915d4cbddceb435e13d81601755714e9fSE Android	tmp_key->name = name;
40255e72915d4cbddceb435e13d81601755714e9fSE Android
41255e72915d4cbddceb435e13d81601755714e9fSE Android	*key_ptr = tmp_key;
42255e72915d4cbddceb435e13d81601755714e9fSE Android	return STATUS_SUCCESS;
43255e72915d4cbddceb435e13d81601755714e9fSE Android}
44255e72915d4cbddceb435e13d81601755714e9fSE Android
45255e72915d4cbddceb435e13d81601755714e9fSE Androidhidden_def(sepol_iface_key_create)
46255e72915d4cbddceb435e13d81601755714e9fSE Android
47255e72915d4cbddceb435e13d81601755714e9fSE Androidvoid sepol_iface_key_unpack(const sepol_iface_key_t * key, const char **name)
48255e72915d4cbddceb435e13d81601755714e9fSE Android{
49255e72915d4cbddceb435e13d81601755714e9fSE Android
50255e72915d4cbddceb435e13d81601755714e9fSE Android	*name = key->name;
51255e72915d4cbddceb435e13d81601755714e9fSE Android}
52255e72915d4cbddceb435e13d81601755714e9fSE Android
53255e72915d4cbddceb435e13d81601755714e9fSE Androidhidden_def(sepol_iface_key_unpack)
54255e72915d4cbddceb435e13d81601755714e9fSE Android
55255e72915d4cbddceb435e13d81601755714e9fSE Androidint sepol_iface_key_extract(sepol_handle_t * handle,
56255e72915d4cbddceb435e13d81601755714e9fSE Android			    const sepol_iface_t * iface,
57255e72915d4cbddceb435e13d81601755714e9fSE Android			    sepol_iface_key_t ** key_ptr)
58255e72915d4cbddceb435e13d81601755714e9fSE Android{
59255e72915d4cbddceb435e13d81601755714e9fSE Android
60255e72915d4cbddceb435e13d81601755714e9fSE Android	if (sepol_iface_key_create(handle, iface->name, key_ptr) < 0) {
61255e72915d4cbddceb435e13d81601755714e9fSE Android		ERR(handle, "could not extract key from "
62255e72915d4cbddceb435e13d81601755714e9fSE Android		    "interface %s", iface->name);
63255e72915d4cbddceb435e13d81601755714e9fSE Android		return STATUS_ERR;
64255e72915d4cbddceb435e13d81601755714e9fSE Android	}
65255e72915d4cbddceb435e13d81601755714e9fSE Android
66255e72915d4cbddceb435e13d81601755714e9fSE Android	return STATUS_SUCCESS;
67255e72915d4cbddceb435e13d81601755714e9fSE Android}
68255e72915d4cbddceb435e13d81601755714e9fSE Android
69255e72915d4cbddceb435e13d81601755714e9fSE Androidvoid sepol_iface_key_free(sepol_iface_key_t * key)
70255e72915d4cbddceb435e13d81601755714e9fSE Android{
71255e72915d4cbddceb435e13d81601755714e9fSE Android	free(key);
72255e72915d4cbddceb435e13d81601755714e9fSE Android}
73255e72915d4cbddceb435e13d81601755714e9fSE Android
74255e72915d4cbddceb435e13d81601755714e9fSE Androidint sepol_iface_compare(const sepol_iface_t * iface,
75255e72915d4cbddceb435e13d81601755714e9fSE Android			const sepol_iface_key_t * key)
76255e72915d4cbddceb435e13d81601755714e9fSE Android{
77255e72915d4cbddceb435e13d81601755714e9fSE Android
78255e72915d4cbddceb435e13d81601755714e9fSE Android	return strcmp(iface->name, key->name);
79255e72915d4cbddceb435e13d81601755714e9fSE Android}
80255e72915d4cbddceb435e13d81601755714e9fSE Android
81255e72915d4cbddceb435e13d81601755714e9fSE Androidint sepol_iface_compare2(const sepol_iface_t * iface,
82255e72915d4cbddceb435e13d81601755714e9fSE Android			 const sepol_iface_t * iface2)
83255e72915d4cbddceb435e13d81601755714e9fSE Android{
84255e72915d4cbddceb435e13d81601755714e9fSE Android
85255e72915d4cbddceb435e13d81601755714e9fSE Android	return strcmp(iface->name, iface2->name);
86255e72915d4cbddceb435e13d81601755714e9fSE Android}
87255e72915d4cbddceb435e13d81601755714e9fSE Android
88255e72915d4cbddceb435e13d81601755714e9fSE Android/* Create */
89255e72915d4cbddceb435e13d81601755714e9fSE Androidint sepol_iface_create(sepol_handle_t * handle, sepol_iface_t ** iface)
90255e72915d4cbddceb435e13d81601755714e9fSE Android{
91255e72915d4cbddceb435e13d81601755714e9fSE Android
92255e72915d4cbddceb435e13d81601755714e9fSE Android	sepol_iface_t *tmp_iface =
93255e72915d4cbddceb435e13d81601755714e9fSE Android	    (sepol_iface_t *) malloc(sizeof(sepol_iface_t));
94255e72915d4cbddceb435e13d81601755714e9fSE Android
95255e72915d4cbddceb435e13d81601755714e9fSE Android	if (!tmp_iface) {
96255e72915d4cbddceb435e13d81601755714e9fSE Android		ERR(handle, "out of memory, could not create "
97255e72915d4cbddceb435e13d81601755714e9fSE Android		    "interface record");
98255e72915d4cbddceb435e13d81601755714e9fSE Android		return STATUS_ERR;
99255e72915d4cbddceb435e13d81601755714e9fSE Android	}
100255e72915d4cbddceb435e13d81601755714e9fSE Android
101255e72915d4cbddceb435e13d81601755714e9fSE Android	tmp_iface->name = NULL;
102255e72915d4cbddceb435e13d81601755714e9fSE Android	tmp_iface->netif_con = NULL;
103255e72915d4cbddceb435e13d81601755714e9fSE Android	tmp_iface->netmsg_con = NULL;
104255e72915d4cbddceb435e13d81601755714e9fSE Android	*iface = tmp_iface;
105255e72915d4cbddceb435e13d81601755714e9fSE Android
106255e72915d4cbddceb435e13d81601755714e9fSE Android	return STATUS_SUCCESS;
107255e72915d4cbddceb435e13d81601755714e9fSE Android}
108255e72915d4cbddceb435e13d81601755714e9fSE Android
109255e72915d4cbddceb435e13d81601755714e9fSE Androidhidden_def(sepol_iface_create)
110255e72915d4cbddceb435e13d81601755714e9fSE Android
111255e72915d4cbddceb435e13d81601755714e9fSE Android/* Name */
112255e72915d4cbddceb435e13d81601755714e9fSE Androidconst char *sepol_iface_get_name(const sepol_iface_t * iface)
113255e72915d4cbddceb435e13d81601755714e9fSE Android{
114255e72915d4cbddceb435e13d81601755714e9fSE Android
115255e72915d4cbddceb435e13d81601755714e9fSE Android	return iface->name;
116255e72915d4cbddceb435e13d81601755714e9fSE Android}
117255e72915d4cbddceb435e13d81601755714e9fSE Android
118255e72915d4cbddceb435e13d81601755714e9fSE Androidhidden_def(sepol_iface_get_name)
119255e72915d4cbddceb435e13d81601755714e9fSE Android
120255e72915d4cbddceb435e13d81601755714e9fSE Androidint sepol_iface_set_name(sepol_handle_t * handle,
121255e72915d4cbddceb435e13d81601755714e9fSE Android			 sepol_iface_t * iface, const char *name)
122255e72915d4cbddceb435e13d81601755714e9fSE Android{
123255e72915d4cbddceb435e13d81601755714e9fSE Android
124255e72915d4cbddceb435e13d81601755714e9fSE Android	char *tmp_name = strdup(name);
125255e72915d4cbddceb435e13d81601755714e9fSE Android	if (!tmp_name) {
126255e72915d4cbddceb435e13d81601755714e9fSE Android		ERR(handle, "out of memory, " "could not set interface name");
127255e72915d4cbddceb435e13d81601755714e9fSE Android		return STATUS_ERR;
128255e72915d4cbddceb435e13d81601755714e9fSE Android	}
129255e72915d4cbddceb435e13d81601755714e9fSE Android	free(iface->name);
130255e72915d4cbddceb435e13d81601755714e9fSE Android	iface->name = tmp_name;
131255e72915d4cbddceb435e13d81601755714e9fSE Android	return STATUS_SUCCESS;
132255e72915d4cbddceb435e13d81601755714e9fSE Android}
133255e72915d4cbddceb435e13d81601755714e9fSE Android
134255e72915d4cbddceb435e13d81601755714e9fSE Androidhidden_def(sepol_iface_set_name)
135255e72915d4cbddceb435e13d81601755714e9fSE Android
136255e72915d4cbddceb435e13d81601755714e9fSE Android/* Interface Context */
137255e72915d4cbddceb435e13d81601755714e9fSE Androidsepol_context_t *sepol_iface_get_ifcon(const sepol_iface_t * iface)
138255e72915d4cbddceb435e13d81601755714e9fSE Android{
139255e72915d4cbddceb435e13d81601755714e9fSE Android
140255e72915d4cbddceb435e13d81601755714e9fSE Android	return iface->netif_con;
141255e72915d4cbddceb435e13d81601755714e9fSE Android}
142255e72915d4cbddceb435e13d81601755714e9fSE Android
143255e72915d4cbddceb435e13d81601755714e9fSE Androidhidden_def(sepol_iface_get_ifcon)
144255e72915d4cbddceb435e13d81601755714e9fSE Android
145255e72915d4cbddceb435e13d81601755714e9fSE Androidint sepol_iface_set_ifcon(sepol_handle_t * handle,
146255e72915d4cbddceb435e13d81601755714e9fSE Android			  sepol_iface_t * iface, sepol_context_t * con)
147255e72915d4cbddceb435e13d81601755714e9fSE Android{
148255e72915d4cbddceb435e13d81601755714e9fSE Android
149255e72915d4cbddceb435e13d81601755714e9fSE Android	sepol_context_t *newcon;
150255e72915d4cbddceb435e13d81601755714e9fSE Android
151255e72915d4cbddceb435e13d81601755714e9fSE Android	if (sepol_context_clone(handle, con, &newcon) < 0) {
152255e72915d4cbddceb435e13d81601755714e9fSE Android		ERR(handle, "out of memory, could not set interface context");
153255e72915d4cbddceb435e13d81601755714e9fSE Android		return STATUS_ERR;
154255e72915d4cbddceb435e13d81601755714e9fSE Android	}
155255e72915d4cbddceb435e13d81601755714e9fSE Android
156255e72915d4cbddceb435e13d81601755714e9fSE Android	sepol_context_free(iface->netif_con);
157255e72915d4cbddceb435e13d81601755714e9fSE Android	iface->netif_con = newcon;
158255e72915d4cbddceb435e13d81601755714e9fSE Android	return STATUS_SUCCESS;
159255e72915d4cbddceb435e13d81601755714e9fSE Android}
160255e72915d4cbddceb435e13d81601755714e9fSE Android
161255e72915d4cbddceb435e13d81601755714e9fSE Androidhidden_def(sepol_iface_set_ifcon)
162255e72915d4cbddceb435e13d81601755714e9fSE Android
163255e72915d4cbddceb435e13d81601755714e9fSE Android/* Message Context */
164255e72915d4cbddceb435e13d81601755714e9fSE Androidsepol_context_t *sepol_iface_get_msgcon(const sepol_iface_t * iface)
165255e72915d4cbddceb435e13d81601755714e9fSE Android{
166255e72915d4cbddceb435e13d81601755714e9fSE Android
167255e72915d4cbddceb435e13d81601755714e9fSE Android	return iface->netmsg_con;
168255e72915d4cbddceb435e13d81601755714e9fSE Android}
169255e72915d4cbddceb435e13d81601755714e9fSE Android
170255e72915d4cbddceb435e13d81601755714e9fSE Androidhidden_def(sepol_iface_get_msgcon)
171255e72915d4cbddceb435e13d81601755714e9fSE Android
172255e72915d4cbddceb435e13d81601755714e9fSE Androidint sepol_iface_set_msgcon(sepol_handle_t * handle,
173255e72915d4cbddceb435e13d81601755714e9fSE Android			   sepol_iface_t * iface, sepol_context_t * con)
174255e72915d4cbddceb435e13d81601755714e9fSE Android{
175255e72915d4cbddceb435e13d81601755714e9fSE Android
176255e72915d4cbddceb435e13d81601755714e9fSE Android	sepol_context_t *newcon;
177255e72915d4cbddceb435e13d81601755714e9fSE Android	if (sepol_context_clone(handle, con, &newcon) < 0) {
178255e72915d4cbddceb435e13d81601755714e9fSE Android		ERR(handle, "out of memory, could not set message context");
179255e72915d4cbddceb435e13d81601755714e9fSE Android		return STATUS_ERR;
180255e72915d4cbddceb435e13d81601755714e9fSE Android	}
181255e72915d4cbddceb435e13d81601755714e9fSE Android
182255e72915d4cbddceb435e13d81601755714e9fSE Android	sepol_context_free(iface->netmsg_con);
183255e72915d4cbddceb435e13d81601755714e9fSE Android	iface->netmsg_con = newcon;
184255e72915d4cbddceb435e13d81601755714e9fSE Android	return STATUS_SUCCESS;
185255e72915d4cbddceb435e13d81601755714e9fSE Android}
186255e72915d4cbddceb435e13d81601755714e9fSE Android
187255e72915d4cbddceb435e13d81601755714e9fSE Androidhidden_def(sepol_iface_set_msgcon)
188255e72915d4cbddceb435e13d81601755714e9fSE Android
189255e72915d4cbddceb435e13d81601755714e9fSE Android/* Deep copy clone */
190255e72915d4cbddceb435e13d81601755714e9fSE Androidint sepol_iface_clone(sepol_handle_t * handle,
191255e72915d4cbddceb435e13d81601755714e9fSE Android		      const sepol_iface_t * iface, sepol_iface_t ** iface_ptr)
192255e72915d4cbddceb435e13d81601755714e9fSE Android{
193255e72915d4cbddceb435e13d81601755714e9fSE Android
194255e72915d4cbddceb435e13d81601755714e9fSE Android	sepol_iface_t *new_iface = NULL;
195255e72915d4cbddceb435e13d81601755714e9fSE Android	if (sepol_iface_create(handle, &new_iface) < 0)
196255e72915d4cbddceb435e13d81601755714e9fSE Android		goto err;
197255e72915d4cbddceb435e13d81601755714e9fSE Android
198255e72915d4cbddceb435e13d81601755714e9fSE Android	if (sepol_iface_set_name(handle, new_iface, iface->name) < 0)
199255e72915d4cbddceb435e13d81601755714e9fSE Android		goto err;
200255e72915d4cbddceb435e13d81601755714e9fSE Android
201255e72915d4cbddceb435e13d81601755714e9fSE Android	if (iface->netif_con &&
202255e72915d4cbddceb435e13d81601755714e9fSE Android	    (sepol_context_clone
203255e72915d4cbddceb435e13d81601755714e9fSE Android	     (handle, iface->netif_con, &new_iface->netif_con) < 0))
204255e72915d4cbddceb435e13d81601755714e9fSE Android		goto err;
205255e72915d4cbddceb435e13d81601755714e9fSE Android
206255e72915d4cbddceb435e13d81601755714e9fSE Android	if (iface->netmsg_con &&
207255e72915d4cbddceb435e13d81601755714e9fSE Android	    (sepol_context_clone
208255e72915d4cbddceb435e13d81601755714e9fSE Android	     (handle, iface->netmsg_con, &new_iface->netmsg_con) < 0))
209255e72915d4cbddceb435e13d81601755714e9fSE Android		goto err;
210255e72915d4cbddceb435e13d81601755714e9fSE Android
211255e72915d4cbddceb435e13d81601755714e9fSE Android	*iface_ptr = new_iface;
212255e72915d4cbddceb435e13d81601755714e9fSE Android	return STATUS_SUCCESS;
213255e72915d4cbddceb435e13d81601755714e9fSE Android
214255e72915d4cbddceb435e13d81601755714e9fSE Android      err:
215255e72915d4cbddceb435e13d81601755714e9fSE Android	ERR(handle, "could not clone interface record");
216255e72915d4cbddceb435e13d81601755714e9fSE Android	sepol_iface_free(new_iface);
217255e72915d4cbddceb435e13d81601755714e9fSE Android	return STATUS_ERR;
218255e72915d4cbddceb435e13d81601755714e9fSE Android}
219255e72915d4cbddceb435e13d81601755714e9fSE Android
220255e72915d4cbddceb435e13d81601755714e9fSE Android/* Destroy */
221255e72915d4cbddceb435e13d81601755714e9fSE Androidvoid sepol_iface_free(sepol_iface_t * iface)
222255e72915d4cbddceb435e13d81601755714e9fSE Android{
223255e72915d4cbddceb435e13d81601755714e9fSE Android
224255e72915d4cbddceb435e13d81601755714e9fSE Android	if (!iface)
225255e72915d4cbddceb435e13d81601755714e9fSE Android		return;
226255e72915d4cbddceb435e13d81601755714e9fSE Android
227255e72915d4cbddceb435e13d81601755714e9fSE Android	free(iface->name);
228255e72915d4cbddceb435e13d81601755714e9fSE Android	sepol_context_free(iface->netif_con);
229255e72915d4cbddceb435e13d81601755714e9fSE Android	sepol_context_free(iface->netmsg_con);
230255e72915d4cbddceb435e13d81601755714e9fSE Android	free(iface);
231255e72915d4cbddceb435e13d81601755714e9fSE Android}
232255e72915d4cbddceb435e13d81601755714e9fSE Android
233255e72915d4cbddceb435e13d81601755714e9fSE Androidhidden_def(sepol_iface_free)
234