1 /* 2 * (C) 2005-2011 by Pablo Neira Ayuso <pablo (at) netfilter.org> 3 * Harald Welte <laforge (at) 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 15 struct nfct_handle *nfct_open_nfnl(struct nfnl_handle *nfnlh, 16 uint8_t subsys_id, 17 unsigned int subscriptions) 18 { 19 20 return nfct_open_nfnl2(nfnlh, subsys_id, subscriptions, true); 21 } 22 23 struct nfct_handle *nfct_open_nfnl2(struct nfnl_handle *nfnlh, 24 uint8_t subsys_id, 25 unsigned int subscriptions, bool bind) 26 { 27 struct nfct_handle *cth; 28 29 cth = malloc(sizeof(struct nfct_handle)); 30 if (!cth) 31 return NULL; 32 memset(cth, 0, sizeof(*cth)); 33 cth->nfnlh = nfnlh; 34 35 if (subsys_id == 0 || subsys_id == NFNL_SUBSYS_CTNETLINK) { 36 cth->nfnlssh_ct = nfnl_subsys_open2(cth->nfnlh, 37 NFNL_SUBSYS_CTNETLINK, 38 IPCTNL_MSG_MAX, 39 subscriptions, 40 bind); 41 if (!cth->nfnlssh_ct) 42 goto out_free; 43 } 44 45 if (subsys_id == 0 || subsys_id == NFNL_SUBSYS_CTNETLINK_EXP) { 46 cth->nfnlssh_exp = nfnl_subsys_open2(cth->nfnlh, 47 NFNL_SUBSYS_CTNETLINK_EXP, 48 IPCTNL_MSG_EXP_MAX, 49 subscriptions, 50 bind); 51 if (!cth->nfnlssh_exp) 52 goto out_free; 53 } 54 55 return cth; 56 57 out_free: 58 if (cth->nfnlssh_exp) { 59 nfnl_subsys_close(cth->nfnlssh_exp); 60 cth->nfnlssh_exp = NULL; 61 } 62 if (cth->nfnlssh_ct) { 63 nfnl_subsys_close(cth->nfnlssh_ct); 64 cth->nfnlssh_ct = NULL; 65 } 66 free(cth); 67 return NULL; 68 } 69 /** 70 * \defgroup LibrarySetup Library setup 71 * @{ 72 */ 73 74 75 /** 76 * nfct_open - open a ctnetlink handler 77 * \param subsys_id can be NFNL_SUBSYS_CTNETLINK or NFNL_SUBSYS_CTNETLINK_EXP 78 * \param subscriptions ctnetlink groups to subscribe to events 79 * 80 * This function returns a handler to send commands to and receive replies from 81 * kernel-space. You can pass the following subsystem IDs: 82 * 83 * - NFNL_SUBSYS_CTNETLINK: if you are only interested in conntrack operations 84 * (excluding expectations). 85 * - NFNL_SUBSYS_CTNETLINK_EXP: if you are only interested in expectation 86 * operations (exclude conntracks). 87 * - NFNL_SUBSYS_NONE: if you are interested in both conntrack and expectation 88 * operations. 89 * 90 * On error, NULL is returned and errno is explicitly set. 91 */ 92 struct nfct_handle *nfct_open(uint8_t subsys_id, unsigned subscriptions) 93 { 94 struct nfnl_handle *nfnlh = nfnl_open(); 95 struct nfct_handle *nfcth; 96 97 if (!nfnlh) 98 return NULL; 99 100 nfcth = nfct_open_nfnl(nfnlh, subsys_id, subscriptions); 101 if (!nfcth) 102 nfnl_close(nfnlh); 103 return nfcth; 104 } 105 106 /** 107 * nfct_open2 - open a ctnetlink handler by given fd 108 * \param subsys_id can be NFNL_SUBSYS_CTNETLINK or NFNL_SUBSYS_CTNETLINK_EXP 109 * \param subscriptions ctnetlink groups to subscribe to events 110 * \param fd use bound file descriptor to get nfnl_handle 111 * 112 * This function returns a handler to send commands to and receive replies from 113 * kernel-space. You can pass the following subsystem IDs: 114 * 115 * - NFNL_SUBSYS_CTNETLINK: if you are only interested in conntrack operations 116 * (excluding expectations). 117 * - NFNL_SUBSYS_CTNETLINK_EXP: if you are only interested in expectation 118 * operations (exclude conntracks). 119 * - NFNL_SUBSYS_NONE: if you are interested in both conntrack and expectation 120 * operations. 121 * 122 * On error, NULL is returned and errno is explicitly set. 123 */ 124 struct nfct_handle *nfct_open2(uint8_t subsys_id, unsigned subscriptions, int fd) 125 { 126 struct nfnl_handle *nfnlh = nfnl_open2(fd, false); 127 struct nfct_handle *nfcth; 128 129 if (!nfnlh) 130 return NULL; 131 132 nfcth = nfct_open_nfnl2(nfnlh, subsys_id, subscriptions, false); 133 if (!nfcth) { 134 nfnl_close2(nfnlh); 135 } 136 return nfcth; 137 } 138 139 /** 140 * nfct_close - close a ctnetlink handler 141 * \param cth handler obtained via nfct_open() 142 * 143 * This function returns -1 on error and errno is explicitly set. 144 */ 145 int nfct_close(struct nfct_handle *cth) 146 { 147 return nfct_close2(cth, false); 148 } 149 150 /** 151 * nfct_close2 - close a ctnetlink handler 152 * \param cth handler obtained via nfct_open() 153 * \param keep_fd to indicate not close the file descriptor 154 * 155 * This function returns -1 on error and errno is explicitly set. 156 */ 157 int nfct_close2(struct nfct_handle *cth, bool keep_fd) 158 { 159 int err; 160 161 if (cth->nfnlssh_exp) { 162 nfnl_subsys_close(cth->nfnlssh_exp); 163 cth->nfnlssh_exp = NULL; 164 } 165 if (cth->nfnlssh_ct) { 166 nfnl_subsys_close(cth->nfnlssh_ct); 167 cth->nfnlssh_ct = NULL; 168 } 169 170 /* required by the new API */ 171 cth->cb = NULL; 172 cth->cb2 = NULL; 173 cth->expect_cb = NULL; 174 cth->expect_cb2 = NULL; 175 free(cth->nfnl_cb_ct.data); 176 free(cth->nfnl_cb_exp.data); 177 178 cth->nfnl_cb_ct.call = NULL; 179 cth->nfnl_cb_ct.data = NULL; 180 cth->nfnl_cb_ct.attr_count = 0; 181 182 cth->nfnl_cb_exp.call = NULL; 183 cth->nfnl_cb_exp.data = NULL; 184 cth->nfnl_cb_exp.attr_count = 0; 185 186 if (keep_fd) 187 err = nfnl_close2(cth->nfnlh); 188 else 189 err = nfnl_close(cth->nfnlh); 190 free(cth); 191 192 return err; 193 } 194 195 /** 196 * nfct_fd - get the Netlink file descriptor of one existing ctnetlink handler 197 * \param cth handler obtained via nfct_open() 198 */ 199 int nfct_fd(struct nfct_handle *cth) 200 { 201 return nfnl_fd(cth->nfnlh); 202 } 203 204 const struct nfnl_handle *nfct_nfnlh(struct nfct_handle *cth) 205 { 206 return cth->nfnlh; 207 } 208 209 /** 210 * @} 211 */ 212