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	free(key->name);
77	free(key);
78}
79
80int sepol_iface_compare(const sepol_iface_t * iface,
81			const sepol_iface_key_t * key)
82{
83
84	return strcmp(iface->name, key->name);
85}
86
87int sepol_iface_compare2(const sepol_iface_t * iface,
88			 const sepol_iface_t * iface2)
89{
90
91	return strcmp(iface->name, iface2->name);
92}
93
94/* Create */
95int sepol_iface_create(sepol_handle_t * handle, sepol_iface_t ** iface)
96{
97
98	sepol_iface_t *tmp_iface =
99	    (sepol_iface_t *) malloc(sizeof(sepol_iface_t));
100
101	if (!tmp_iface) {
102		ERR(handle, "out of memory, could not create "
103		    "interface record");
104		return STATUS_ERR;
105	}
106
107	tmp_iface->name = NULL;
108	tmp_iface->netif_con = NULL;
109	tmp_iface->netmsg_con = NULL;
110	*iface = tmp_iface;
111
112	return STATUS_SUCCESS;
113}
114
115hidden_def(sepol_iface_create)
116
117/* Name */
118const char *sepol_iface_get_name(const sepol_iface_t * iface)
119{
120
121	return iface->name;
122}
123
124hidden_def(sepol_iface_get_name)
125
126int sepol_iface_set_name(sepol_handle_t * handle,
127			 sepol_iface_t * iface, const char *name)
128{
129
130	char *tmp_name = strdup(name);
131	if (!tmp_name) {
132		ERR(handle, "out of memory, " "could not set interface name");
133		return STATUS_ERR;
134	}
135	free(iface->name);
136	iface->name = tmp_name;
137	return STATUS_SUCCESS;
138}
139
140hidden_def(sepol_iface_set_name)
141
142/* Interface Context */
143sepol_context_t *sepol_iface_get_ifcon(const sepol_iface_t * iface)
144{
145
146	return iface->netif_con;
147}
148
149hidden_def(sepol_iface_get_ifcon)
150
151int sepol_iface_set_ifcon(sepol_handle_t * handle,
152			  sepol_iface_t * iface, sepol_context_t * con)
153{
154
155	sepol_context_t *newcon;
156
157	if (sepol_context_clone(handle, con, &newcon) < 0) {
158		ERR(handle, "out of memory, could not set interface context");
159		return STATUS_ERR;
160	}
161
162	sepol_context_free(iface->netif_con);
163	iface->netif_con = newcon;
164	return STATUS_SUCCESS;
165}
166
167hidden_def(sepol_iface_set_ifcon)
168
169/* Message Context */
170sepol_context_t *sepol_iface_get_msgcon(const sepol_iface_t * iface)
171{
172
173	return iface->netmsg_con;
174}
175
176hidden_def(sepol_iface_get_msgcon)
177
178int sepol_iface_set_msgcon(sepol_handle_t * handle,
179			   sepol_iface_t * iface, sepol_context_t * con)
180{
181
182	sepol_context_t *newcon;
183	if (sepol_context_clone(handle, con, &newcon) < 0) {
184		ERR(handle, "out of memory, could not set message context");
185		return STATUS_ERR;
186	}
187
188	sepol_context_free(iface->netmsg_con);
189	iface->netmsg_con = newcon;
190	return STATUS_SUCCESS;
191}
192
193hidden_def(sepol_iface_set_msgcon)
194
195/* Deep copy clone */
196int sepol_iface_clone(sepol_handle_t * handle,
197		      const sepol_iface_t * iface, sepol_iface_t ** iface_ptr)
198{
199
200	sepol_iface_t *new_iface = NULL;
201	if (sepol_iface_create(handle, &new_iface) < 0)
202		goto err;
203
204	if (sepol_iface_set_name(handle, new_iface, iface->name) < 0)
205		goto err;
206
207	if (iface->netif_con &&
208	    (sepol_context_clone
209	     (handle, iface->netif_con, &new_iface->netif_con) < 0))
210		goto err;
211
212	if (iface->netmsg_con &&
213	    (sepol_context_clone
214	     (handle, iface->netmsg_con, &new_iface->netmsg_con) < 0))
215		goto err;
216
217	*iface_ptr = new_iface;
218	return STATUS_SUCCESS;
219
220      err:
221	ERR(handle, "could not clone interface record");
222	sepol_iface_free(new_iface);
223	return STATUS_ERR;
224}
225
226/* Destroy */
227void sepol_iface_free(sepol_iface_t * iface)
228{
229
230	if (!iface)
231		return;
232
233	free(iface->name);
234	sepol_context_free(iface->netif_con);
235	sepol_context_free(iface->netmsg_con);
236	free(iface);
237}
238
239hidden_def(sepol_iface_free)
240