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 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 */ 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 */ 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 */ 144 int nfct_fd(struct nfct_handle *cth) 145 { 146 return nfnl_fd(cth->nfnlh); 147 } 148 149 const struct nfnl_handle *nfct_nfnlh(struct nfct_handle *cth) 150 { 151 return cth->nfnlh; 152 } 153 154 /** 155 * @} 156 */ 157