1 /*
2 * (C) 2005-2011 by Pablo Neira Ayuso <pablo@netfilter.org>
3 * Harald Welte <laforge@netfilter.org>
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 */
10 #include <libnfnetlink/libnfnetlink.h>
11 #include <libnetfilter_conntrack/libnetfilter_conntrack.h>
12
13 #include "internal/internal.h"
14
nfct_open_nfnl(struct nfnl_handle * nfnlh,uint8_t subsys_id,unsigned int subscriptions)15 struct nfct_handle *nfct_open_nfnl(struct nfnl_handle *nfnlh,
16 uint8_t subsys_id,
17 unsigned int subscriptions)
18 {
19 struct nfct_handle *cth;
20
21 cth = malloc(sizeof(struct nfct_handle));
22 if (!cth)
23 return NULL;
24
25 memset(cth, 0, sizeof(*cth));
26 cth->nfnlh = nfnlh;
27
28 if (subsys_id == 0 || subsys_id == NFNL_SUBSYS_CTNETLINK) {
29 cth->nfnlssh_ct = nfnl_subsys_open(cth->nfnlh,
30 NFNL_SUBSYS_CTNETLINK,
31 IPCTNL_MSG_MAX,
32 subscriptions);
33 if (!cth->nfnlssh_ct)
34 goto out_free;
35 }
36
37 if (subsys_id == 0 || subsys_id == NFNL_SUBSYS_CTNETLINK_EXP) {
38 cth->nfnlssh_exp = nfnl_subsys_open(cth->nfnlh,
39 NFNL_SUBSYS_CTNETLINK_EXP,
40 IPCTNL_MSG_EXP_MAX,
41 subscriptions);
42 if (!cth->nfnlssh_exp)
43 goto out_free;
44 }
45
46 return cth;
47
48 out_free:
49 if (cth->nfnlssh_exp) {
50 nfnl_subsys_close(cth->nfnlssh_exp);
51 cth->nfnlssh_exp = NULL;
52 }
53 if (cth->nfnlssh_ct) {
54 nfnl_subsys_close(cth->nfnlssh_ct);
55 cth->nfnlssh_ct = NULL;
56 }
57 free(cth);
58 return NULL;
59 }
60
61 /**
62 * \defgroup LibrarySetup Library setup
63 * @{
64 */
65
66
67 /**
68 * nfct_open - open a ctnetlink handler
69 * \param subsys_id can be NFNL_SUBSYS_CTNETLINK or NFNL_SUBSYS_CTNETLINK_EXP
70 * \param subscriptions ctnetlink groups to subscribe to events
71 *
72 * This function returns a handler to send commands to and receive replies from
73 * kernel-space. You can pass the following subsystem IDs:
74 *
75 * - NFNL_SUBSYS_CTNETLINK: if you are only interested in conntrack operations
76 * (excluding expectations).
77 * - NFNL_SUBSYS_CTNETLINK_EXP: if you are only interested in expectation
78 * operations (exclude conntracks).
79 * - NFNL_SUBSYS_NONE: if you are interested in both conntrack and expectation
80 * operations.
81 *
82 * On error, NULL is returned and errno is explicitly set.
83 */
nfct_open(uint8_t subsys_id,unsigned subscriptions)84 struct nfct_handle *nfct_open(uint8_t subsys_id, unsigned subscriptions)
85 {
86 struct nfnl_handle *nfnlh = nfnl_open();
87 struct nfct_handle *nfcth;
88
89 if (!nfnlh)
90 return NULL;
91
92 nfcth = nfct_open_nfnl(nfnlh, subsys_id, subscriptions);
93 if (!nfcth)
94 nfnl_close(nfnlh);
95
96 return nfcth;
97 }
98
99 /**
100 * nfct_close - close a ctnetlink handler
101 * \param cth handler obtained via nfct_open()
102 *
103 * This function returns -1 on error and errno is explicitly set.
104 */
nfct_close(struct nfct_handle * cth)105 int nfct_close(struct nfct_handle *cth)
106 {
107 int err;
108
109 if (cth->nfnlssh_exp) {
110 nfnl_subsys_close(cth->nfnlssh_exp);
111 cth->nfnlssh_exp = NULL;
112 }
113 if (cth->nfnlssh_ct) {
114 nfnl_subsys_close(cth->nfnlssh_ct);
115 cth->nfnlssh_ct = NULL;
116 }
117
118 /* required by the new API */
119 cth->cb = NULL;
120 cth->cb2 = NULL;
121 cth->expect_cb = NULL;
122 cth->expect_cb2 = NULL;
123 free(cth->nfnl_cb_ct.data);
124 free(cth->nfnl_cb_exp.data);
125
126 cth->nfnl_cb_ct.call = NULL;
127 cth->nfnl_cb_ct.data = NULL;
128 cth->nfnl_cb_ct.attr_count = 0;
129
130 cth->nfnl_cb_exp.call = NULL;
131 cth->nfnl_cb_exp.data = NULL;
132 cth->nfnl_cb_exp.attr_count = 0;
133
134 err = nfnl_close(cth->nfnlh);
135 free(cth);
136
137 return err;
138 }
139
140 /**
141 * nfct_fd - get the Netlink file descriptor of one existing ctnetlink handler
142 * \param cth handler obtained via nfct_open()
143 */
nfct_fd(struct nfct_handle * cth)144 int nfct_fd(struct nfct_handle *cth)
145 {
146 return nfnl_fd(cth->nfnlh);
147 }
148
nfct_nfnlh(struct nfct_handle * cth)149 const struct nfnl_handle *nfct_nfnlh(struct nfct_handle *cth)
150 {
151 return cth->nfnlh;
152 }
153
154 /**
155 * @}
156 */
157