Home | History | Annotate | Download | only in src
      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