1#include <stdlib.h>
2#include <string.h>
3
4#include "port_internal.h"
5#include "context_internal.h"
6#include "debug.h"
7
8struct sepol_port {
9	/* Low - High range. Same for single ports. */
10	int low, high;
11
12	/* Protocol */
13	int proto;
14
15	/* Context */
16	sepol_context_t *con;
17};
18
19struct sepol_port_key {
20	/* Low - High range. Same for single ports. */
21	int low, high;
22
23	/* Protocol */
24	int proto;
25};
26
27/* Key */
28int sepol_port_key_create(sepol_handle_t * handle,
29			  int low, int high, int proto,
30			  sepol_port_key_t ** key_ptr)
31{
32
33	sepol_port_key_t *tmp_key =
34	    (sepol_port_key_t *) malloc(sizeof(sepol_port_key_t));
35
36	if (!tmp_key) {
37		ERR(handle, "out of memory, could not create " "port key");
38		return STATUS_ERR;
39	}
40
41	tmp_key->low = low;
42	tmp_key->high = high;
43	tmp_key->proto = proto;
44
45	*key_ptr = tmp_key;
46	return STATUS_SUCCESS;
47}
48
49hidden_def(sepol_port_key_create)
50
51void sepol_port_key_unpack(const sepol_port_key_t * key,
52			   int *low, int *high, int *proto)
53{
54
55	*low = key->low;
56	*high = key->high;
57	*proto = key->proto;
58}
59
60hidden_def(sepol_port_key_unpack)
61
62int sepol_port_key_extract(sepol_handle_t * handle,
63			   const sepol_port_t * port,
64			   sepol_port_key_t ** key_ptr)
65{
66
67	if (sepol_port_key_create
68	    (handle, port->low, port->high, port->proto, key_ptr) < 0) {
69
70		ERR(handle, "could not extract key from port %s %d:%d",
71		    sepol_port_get_proto_str(port->proto),
72		    port->low, port->high);
73
74		return STATUS_ERR;
75	}
76
77	return STATUS_SUCCESS;
78}
79
80void sepol_port_key_free(sepol_port_key_t * key)
81{
82	free(key);
83}
84
85int sepol_port_compare(const sepol_port_t * port, const sepol_port_key_t * key)
86{
87
88	if ((port->low == key->low) &&
89	    (port->high == key->high) && (port->proto == key->proto))
90		return 0;
91
92	if (port->low < key->low)
93		return -1;
94
95	else if (key->low < port->low)
96		return 1;
97
98	else if (port->high < key->high)
99		return -1;
100
101	else if (key->high < port->high)
102		return 1;
103
104	else if (port->proto < key->proto)
105		return -1;
106
107	else
108		return 1;
109}
110
111int sepol_port_compare2(const sepol_port_t * port, const sepol_port_t * port2)
112{
113
114	if ((port->low == port2->low) &&
115	    (port->high == port2->high) && (port->proto == port2->proto))
116		return 0;
117
118	if (port->low < port2->low)
119		return -1;
120
121	else if (port2->low < port->low)
122		return 1;
123
124	else if (port->high < port2->high)
125		return -1;
126
127	else if (port2->high < port->high)
128		return 1;
129
130	else if (port->proto < port2->proto)
131		return -1;
132
133	else
134		return 1;
135}
136
137/* Port */
138int sepol_port_get_low(const sepol_port_t * port)
139{
140
141	return port->low;
142}
143
144hidden_def(sepol_port_get_low)
145
146int sepol_port_get_high(const sepol_port_t * port)
147{
148
149	return port->high;
150}
151
152hidden_def(sepol_port_get_high)
153
154void sepol_port_set_port(sepol_port_t * port, int port_num)
155{
156
157	port->low = port_num;
158	port->high = port_num;
159}
160
161void sepol_port_set_range(sepol_port_t * port, int low, int high)
162{
163
164	port->low = low;
165	port->high = high;
166}
167
168hidden_def(sepol_port_set_range)
169
170/* Protocol */
171int sepol_port_get_proto(const sepol_port_t * port)
172{
173
174	return port->proto;
175}
176
177hidden_def(sepol_port_get_proto)
178
179const char *sepol_port_get_proto_str(int proto)
180{
181
182	switch (proto) {
183	case SEPOL_PROTO_UDP:
184		return "udp";
185	case SEPOL_PROTO_TCP:
186		return "tcp";
187	case SEPOL_PROTO_DCCP:
188		return "dccp";
189	default:
190		return "???";
191	}
192}
193
194hidden_def(sepol_port_get_proto_str)
195
196void sepol_port_set_proto(sepol_port_t * port, int proto)
197{
198
199	port->proto = proto;
200}
201
202hidden_def(sepol_port_set_proto)
203
204/* Create */
205int sepol_port_create(sepol_handle_t * handle, sepol_port_t ** port)
206{
207
208	sepol_port_t *tmp_port = (sepol_port_t *) malloc(sizeof(sepol_port_t));
209
210	if (!tmp_port) {
211		ERR(handle, "out of memory, could not create " "port record");
212		return STATUS_ERR;
213	}
214
215	tmp_port->low = 0;
216	tmp_port->high = 0;
217	tmp_port->proto = SEPOL_PROTO_UDP;
218	tmp_port->con = NULL;
219	*port = tmp_port;
220
221	return STATUS_SUCCESS;
222}
223
224hidden_def(sepol_port_create)
225
226/* Deep copy clone */
227int sepol_port_clone(sepol_handle_t * handle,
228		     const sepol_port_t * port, sepol_port_t ** port_ptr)
229{
230
231	sepol_port_t *new_port = NULL;
232	if (sepol_port_create(handle, &new_port) < 0)
233		goto err;
234
235	new_port->low = port->low;
236	new_port->high = port->high;
237	new_port->proto = port->proto;
238
239	if (port->con &&
240	    (sepol_context_clone(handle, port->con, &new_port->con) < 0))
241		goto err;
242
243	*port_ptr = new_port;
244	return STATUS_SUCCESS;
245
246      err:
247	ERR(handle, "could not clone port record");
248	sepol_port_free(new_port);
249	return STATUS_ERR;
250}
251
252/* Destroy */
253void sepol_port_free(sepol_port_t * port)
254{
255
256	if (!port)
257		return;
258
259	sepol_context_free(port->con);
260	free(port);
261}
262
263hidden_def(sepol_port_free)
264
265/* Context */
266sepol_context_t *sepol_port_get_con(const sepol_port_t * port)
267{
268
269	return port->con;
270}
271
272hidden_def(sepol_port_get_con)
273
274int sepol_port_set_con(sepol_handle_t * handle,
275		       sepol_port_t * port, sepol_context_t * con)
276{
277
278	sepol_context_t *newcon;
279
280	if (sepol_context_clone(handle, con, &newcon) < 0) {
281		ERR(handle, "out of memory, could not set port context");
282		return STATUS_ERR;
283	}
284
285	sepol_context_free(port->con);
286	port->con = newcon;
287	return STATUS_SUCCESS;
288}
289
290hidden_def(sepol_port_set_con)
291