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
50
51void sepol_iface_key_unpack(const sepol_iface_key_t * key, const char **name)
52{
53
54	*name = key->name;
55}
56
57
58int sepol_iface_key_extract(sepol_handle_t * handle,
59			    const sepol_iface_t * iface,
60			    sepol_iface_key_t ** key_ptr)
61{
62
63	if (sepol_iface_key_create(handle, iface->name, key_ptr) < 0) {
64		ERR(handle, "could not extract key from "
65		    "interface %s", iface->name);
66		return STATUS_ERR;
67	}
68
69	return STATUS_SUCCESS;
70}
71
72void sepol_iface_key_free(sepol_iface_key_t * key)
73{
74	if (!key)
75		return;
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
115
116/* Name */
117const char *sepol_iface_get_name(const sepol_iface_t * iface)
118{
119
120	return iface->name;
121}
122
123
124int sepol_iface_set_name(sepol_handle_t * handle,
125			 sepol_iface_t * iface, const char *name)
126{
127
128	char *tmp_name = strdup(name);
129	if (!tmp_name) {
130		ERR(handle, "out of memory, " "could not set interface name");
131		return STATUS_ERR;
132	}
133	free(iface->name);
134	iface->name = tmp_name;
135	return STATUS_SUCCESS;
136}
137
138
139/* Interface Context */
140sepol_context_t *sepol_iface_get_ifcon(const sepol_iface_t * iface)
141{
142
143	return iface->netif_con;
144}
145
146
147int sepol_iface_set_ifcon(sepol_handle_t * handle,
148			  sepol_iface_t * iface, sepol_context_t * con)
149{
150
151	sepol_context_t *newcon;
152
153	if (sepol_context_clone(handle, con, &newcon) < 0) {
154		ERR(handle, "out of memory, could not set interface context");
155		return STATUS_ERR;
156	}
157
158	sepol_context_free(iface->netif_con);
159	iface->netif_con = newcon;
160	return STATUS_SUCCESS;
161}
162
163
164/* Message Context */
165sepol_context_t *sepol_iface_get_msgcon(const sepol_iface_t * iface)
166{
167
168	return iface->netmsg_con;
169}
170
171
172int sepol_iface_set_msgcon(sepol_handle_t * handle,
173			   sepol_iface_t * iface, sepol_context_t * con)
174{
175
176	sepol_context_t *newcon;
177	if (sepol_context_clone(handle, con, &newcon) < 0) {
178		ERR(handle, "out of memory, could not set message context");
179		return STATUS_ERR;
180	}
181
182	sepol_context_free(iface->netmsg_con);
183	iface->netmsg_con = newcon;
184	return STATUS_SUCCESS;
185}
186
187
188/* Deep copy clone */
189int sepol_iface_clone(sepol_handle_t * handle,
190		      const sepol_iface_t * iface, sepol_iface_t ** iface_ptr)
191{
192
193	sepol_iface_t *new_iface = NULL;
194	if (sepol_iface_create(handle, &new_iface) < 0)
195		goto err;
196
197	if (sepol_iface_set_name(handle, new_iface, iface->name) < 0)
198		goto err;
199
200	if (iface->netif_con &&
201	    (sepol_context_clone
202	     (handle, iface->netif_con, &new_iface->netif_con) < 0))
203		goto err;
204
205	if (iface->netmsg_con &&
206	    (sepol_context_clone
207	     (handle, iface->netmsg_con, &new_iface->netmsg_con) < 0))
208		goto err;
209
210	*iface_ptr = new_iface;
211	return STATUS_SUCCESS;
212
213      err:
214	ERR(handle, "could not clone interface record");
215	sepol_iface_free(new_iface);
216	return STATUS_ERR;
217}
218
219/* Destroy */
220void sepol_iface_free(sepol_iface_t * iface)
221{
222
223	if (!iface)
224		return;
225
226	free(iface->name);
227	sepol_context_free(iface->netif_con);
228	sepol_context_free(iface->netmsg_con);
229	free(iface);
230}
231
232