1#include <stdlib.h>
2#include <string.h>
3
4#include "iface_internal.h"
5#include "context_internal.h"
6#include "debug.h"
7
8struct sepol_iface {
9
10	/* Interface name */
11	char *name;
12
13	/* Interface context */
14	sepol_context_t *netif_con;
15
16	/* Message context */
17	sepol_context_t *netmsg_con;
18};
19
20struct sepol_iface_key {
21
22	/* Interface name */
23	char *name;
24};
25
26/* Key */
27int sepol_iface_key_create(sepol_handle_t * handle,
28			   const char *name, sepol_iface_key_t ** key_ptr)
29{
30
31	sepol_iface_key_t *tmp_key =
32	    (sepol_iface_key_t *) malloc(sizeof(sepol_iface_key_t));
33
34	if (!tmp_key) {
35		ERR(handle, "out of memory, could not create interface key");
36		return STATUS_ERR;
37	}
38
39	tmp_key->name = strdup(name);
40	if (!tmp_key->name) {
41		ERR(handle, "out of memory, could not create interface key");
42		free(tmp_key);
43		return STATUS_ERR;
44	}
45
46	*key_ptr = tmp_key;
47	return STATUS_SUCCESS;
48}
49
50hidden_def(sepol_iface_key_create)
51
52void sepol_iface_key_unpack(const sepol_iface_key_t * key, const char **name)
53{
54
55	*name = key->name;
56}
57
58hidden_def(sepol_iface_key_unpack)
59
60int sepol_iface_key_extract(sepol_handle_t * handle,
61			    const sepol_iface_t * iface,
62			    sepol_iface_key_t ** key_ptr)
63{
64
65	if (sepol_iface_key_create(handle, iface->name, key_ptr) < 0) {
66		ERR(handle, "could not extract key from "
67		    "interface %s", iface->name);
68		return STATUS_ERR;
69	}
70
71	return STATUS_SUCCESS;
72}
73
74void sepol_iface_key_free(sepol_iface_key_t * key)
75{
76	if (!key)
77		return;
78	free(key->name);
79	free(key);
80}
81
82int sepol_iface_compare(const sepol_iface_t * iface,
83			const sepol_iface_key_t * key)
84{
85
86	return strcmp(iface->name, key->name);
87}
88
89int sepol_iface_compare2(const sepol_iface_t * iface,
90			 const sepol_iface_t * iface2)
91{
92
93	return strcmp(iface->name, iface2->name);
94}
95
96/* Create */
97int sepol_iface_create(sepol_handle_t * handle, sepol_iface_t ** iface)
98{
99
100	sepol_iface_t *tmp_iface =
101	    (sepol_iface_t *) malloc(sizeof(sepol_iface_t));
102
103	if (!tmp_iface) {
104		ERR(handle, "out of memory, could not create "
105		    "interface record");
106		return STATUS_ERR;
107	}
108
109	tmp_iface->name = NULL;
110	tmp_iface->netif_con = NULL;
111	tmp_iface->netmsg_con = NULL;
112	*iface = tmp_iface;
113
114	return STATUS_SUCCESS;
115}
116
117hidden_def(sepol_iface_create)
118
119/* Name */
120const char *sepol_iface_get_name(const sepol_iface_t * iface)
121{
122
123	return iface->name;
124}
125
126hidden_def(sepol_iface_get_name)
127
128int sepol_iface_set_name(sepol_handle_t * handle,
129			 sepol_iface_t * iface, const char *name)
130{
131
132	char *tmp_name = strdup(name);
133	if (!tmp_name) {
134		ERR(handle, "out of memory, " "could not set interface name");
135		return STATUS_ERR;
136	}
137	free(iface->name);
138	iface->name = tmp_name;
139	return STATUS_SUCCESS;
140}
141
142hidden_def(sepol_iface_set_name)
143
144/* Interface Context */
145sepol_context_t *sepol_iface_get_ifcon(const sepol_iface_t * iface)
146{
147
148	return iface->netif_con;
149}
150
151hidden_def(sepol_iface_get_ifcon)
152
153int sepol_iface_set_ifcon(sepol_handle_t * handle,
154			  sepol_iface_t * iface, sepol_context_t * con)
155{
156
157	sepol_context_t *newcon;
158
159	if (sepol_context_clone(handle, con, &newcon) < 0) {
160		ERR(handle, "out of memory, could not set interface context");
161		return STATUS_ERR;
162	}
163
164	sepol_context_free(iface->netif_con);
165	iface->netif_con = newcon;
166	return STATUS_SUCCESS;
167}
168
169hidden_def(sepol_iface_set_ifcon)
170
171/* Message Context */
172sepol_context_t *sepol_iface_get_msgcon(const sepol_iface_t * iface)
173{
174
175	return iface->netmsg_con;
176}
177
178hidden_def(sepol_iface_get_msgcon)
179
180int sepol_iface_set_msgcon(sepol_handle_t * handle,
181			   sepol_iface_t * iface, sepol_context_t * con)
182{
183
184	sepol_context_t *newcon;
185	if (sepol_context_clone(handle, con, &newcon) < 0) {
186		ERR(handle, "out of memory, could not set message context");
187		return STATUS_ERR;
188	}
189
190	sepol_context_free(iface->netmsg_con);
191	iface->netmsg_con = newcon;
192	return STATUS_SUCCESS;
193}
194
195hidden_def(sepol_iface_set_msgcon)
196
197/* Deep copy clone */
198int sepol_iface_clone(sepol_handle_t * handle,
199		      const sepol_iface_t * iface, sepol_iface_t ** iface_ptr)
200{
201
202	sepol_iface_t *new_iface = NULL;
203	if (sepol_iface_create(handle, &new_iface) < 0)
204		goto err;
205
206	if (sepol_iface_set_name(handle, new_iface, iface->name) < 0)
207		goto err;
208
209	if (iface->netif_con &&
210	    (sepol_context_clone
211	     (handle, iface->netif_con, &new_iface->netif_con) < 0))
212		goto err;
213
214	if (iface->netmsg_con &&
215	    (sepol_context_clone
216	     (handle, iface->netmsg_con, &new_iface->netmsg_con) < 0))
217		goto err;
218
219	*iface_ptr = new_iface;
220	return STATUS_SUCCESS;
221
222      err:
223	ERR(handle, "could not clone interface record");
224	sepol_iface_free(new_iface);
225	return STATUS_ERR;
226}
227
228/* Destroy */
229void sepol_iface_free(sepol_iface_t * iface)
230{
231
232	if (!iface)
233		return;
234
235	free(iface->name);
236	sepol_context_free(iface->netif_con);
237	sepol_context_free(iface->netmsg_con);
238	free(iface);
239}
240
241hidden_def(sepol_iface_free)
242