Home | History | Annotate | Download | only in netfilter
      1 /*
      2  * lib/netfilter/log.c	Netfilter Log
      3  *
      4  *	This library is free software; you can redistribute it and/or
      5  *	modify it under the terms of the GNU Lesser General Public
      6  *	License as published by the Free Software Foundation version 2.1
      7  *	of the License.
      8  *
      9  * Copyright (c) 2003-2008 Thomas Graf <tgraf (at) suug.ch>
     10  * Copyright (c) 2007 Philip Craig <philipc (at) snapgear.com>
     11  * Copyright (c) 2007 Secure Computing Corporation
     12  */
     13 
     14 /**
     15  * @ingroup nfnl
     16  * @defgroup log Log
     17  * @brief
     18  * @{
     19  */
     20 
     21 #include <sys/types.h>
     22 #include <linux/netfilter/nfnetlink_log.h>
     23 
     24 #include <netlink-private/netlink.h>
     25 #include <netlink/attr.h>
     26 #include <netlink/netfilter/nfnl.h>
     27 #include <netlink/netfilter/log.h>
     28 
     29 /**
     30  * @name Log Commands
     31  * @{
     32  */
     33 
     34 static int build_log_cmd_request(uint8_t family, uint16_t queuenum,
     35 				 uint8_t command, struct nl_msg **result)
     36 {
     37 	struct nl_msg *msg;
     38 	struct nfulnl_msg_config_cmd cmd;
     39 
     40 	msg = nfnlmsg_alloc_simple(NFNL_SUBSYS_ULOG, NFULNL_MSG_CONFIG, 0,
     41 				   family, queuenum);
     42 	if (msg == NULL)
     43 		return -NLE_NOMEM;
     44 
     45 	cmd.command = command;
     46 	if (nla_put(msg, NFULA_CFG_CMD, sizeof(cmd), &cmd) < 0)
     47 		goto nla_put_failure;
     48 
     49 	*result = msg;
     50 	return 0;
     51 
     52 nla_put_failure:
     53 	nlmsg_free(msg);
     54 	return -NLE_MSGSIZE;
     55 }
     56 
     57 static int send_log_request(struct nl_sock *sk, struct nl_msg *msg)
     58 {
     59 	int err;
     60 
     61 	err = nl_send_auto_complete(sk, msg);
     62 	nlmsg_free(msg);
     63 	if (err < 0)
     64 		return err;
     65 
     66 	return wait_for_ack(sk);
     67 }
     68 
     69 int nfnl_log_build_pf_bind(uint8_t pf, struct nl_msg **result)
     70 {
     71 	return build_log_cmd_request(pf, 0, NFULNL_CFG_CMD_PF_BIND, result);
     72 }
     73 
     74 int nfnl_log_pf_bind(struct nl_sock *nlh, uint8_t pf)
     75 {
     76 	struct nl_msg *msg;
     77 	int err;
     78 
     79 	if ((err = nfnl_log_build_pf_bind(pf, &msg)) < 0)
     80 		return err;
     81 
     82 	return send_log_request(nlh, msg);
     83 }
     84 
     85 int nfnl_log_build_pf_unbind(uint8_t pf, struct nl_msg **result)
     86 {
     87 	return build_log_cmd_request(pf, 0, NFULNL_CFG_CMD_PF_UNBIND, result);
     88 }
     89 
     90 int nfnl_log_pf_unbind(struct nl_sock *nlh, uint8_t pf)
     91 {
     92 	struct nl_msg *msg;
     93 	int err;
     94 
     95 	if ((err = nfnl_log_build_pf_unbind(pf, &msg)) < 0)
     96 		return err;
     97 
     98 	return send_log_request(nlh, msg);
     99 }
    100 
    101 static int nfnl_log_build_request(const struct nfnl_log *log,
    102 				  struct nl_msg **result)
    103 {
    104 	struct nl_msg *msg;
    105 
    106 	if (!nfnl_log_test_group(log))
    107 		return -NLE_MISSING_ATTR;
    108 
    109 	msg = nfnlmsg_alloc_simple(NFNL_SUBSYS_ULOG, NFULNL_MSG_CONFIG, 0,
    110 				   0, nfnl_log_get_group(log));
    111 	if (msg == NULL)
    112 		return -NLE_NOMEM;
    113 
    114 	/* This sucks. The nfnetlink_log interface always expects both
    115 	 * parameters to be present. Needs to be done properly.
    116 	 */
    117 	if (nfnl_log_test_copy_mode(log)) {
    118 		struct nfulnl_msg_config_mode mode;
    119 
    120 		switch (nfnl_log_get_copy_mode(log)) {
    121 		case NFNL_LOG_COPY_NONE:
    122 			mode.copy_mode = NFULNL_COPY_NONE;
    123 			break;
    124 		case NFNL_LOG_COPY_META:
    125 			mode.copy_mode = NFULNL_COPY_META;
    126 			break;
    127 		case NFNL_LOG_COPY_PACKET:
    128 			mode.copy_mode = NFULNL_COPY_PACKET;
    129 			break;
    130 		}
    131 		mode.copy_range = htonl(nfnl_log_get_copy_range(log));
    132 		mode._pad = 0;
    133 
    134 		if (nla_put(msg, NFULA_CFG_MODE, sizeof(mode), &mode) < 0)
    135 			goto nla_put_failure;
    136 	}
    137 
    138 	if (nfnl_log_test_flush_timeout(log) &&
    139 	    nla_put_u32(msg, NFULA_CFG_TIMEOUT,
    140 			htonl(nfnl_log_get_flush_timeout(log))) < 0)
    141 		goto nla_put_failure;
    142 
    143 	if (nfnl_log_test_alloc_size(log) &&
    144 	    nla_put_u32(msg, NFULA_CFG_NLBUFSIZ,
    145 			htonl(nfnl_log_get_alloc_size(log))) < 0)
    146 		goto nla_put_failure;
    147 
    148 	if (nfnl_log_test_queue_threshold(log) &&
    149 	    nla_put_u32(msg, NFULA_CFG_QTHRESH,
    150 			htonl(nfnl_log_get_queue_threshold(log))) < 0)
    151 		goto nla_put_failure;
    152 
    153 	*result = msg;
    154 	return 0;
    155 
    156 nla_put_failure:
    157 	nlmsg_free(msg);
    158 	return -NLE_MSGSIZE;
    159 }
    160 
    161 int nfnl_log_build_create_request(const struct nfnl_log *log,
    162 				  struct nl_msg **result)
    163 {
    164 	struct nfulnl_msg_config_cmd cmd;
    165 	int err;
    166 
    167 	if ((err = nfnl_log_build_request(log, result)) < 0)
    168 		return err;
    169 
    170 	cmd.command = NFULNL_CFG_CMD_BIND;
    171 
    172 	if (nla_put(*result, NFULA_CFG_CMD, sizeof(cmd), &cmd) < 0)
    173 		goto nla_put_failure;
    174 
    175 	return 0;
    176 
    177 nla_put_failure:
    178 	nlmsg_free(*result);
    179 	return -NLE_MSGSIZE;
    180 }
    181 
    182 int nfnl_log_create(struct nl_sock *nlh, const struct nfnl_log *log)
    183 {
    184 	struct nl_msg *msg;
    185 	int err;
    186 
    187 	if ((err = nfnl_log_build_create_request(log, &msg)) < 0)
    188 		return err;
    189 
    190 	return send_log_request(nlh, msg);
    191 }
    192 
    193 int nfnl_log_build_change_request(const struct nfnl_log *log,
    194 				  struct nl_msg **result)
    195 {
    196 	return nfnl_log_build_request(log, result);
    197 }
    198 
    199 int nfnl_log_change(struct nl_sock *nlh, const struct nfnl_log *log)
    200 {
    201 	struct nl_msg *msg;
    202 	int err;
    203 
    204 	if ((err = nfnl_log_build_change_request(log, &msg)) < 0)
    205 		return err;
    206 
    207 	return send_log_request(nlh, msg);
    208 }
    209 
    210 int nfnl_log_build_delete_request(const struct nfnl_log *log,
    211 				  struct nl_msg **result)
    212 {
    213 	if (!nfnl_log_test_group(log))
    214 		return -NLE_MISSING_ATTR;
    215 
    216 	return build_log_cmd_request(0, nfnl_log_get_group(log),
    217 				     NFULNL_CFG_CMD_UNBIND, result);
    218 }
    219 
    220 int nfnl_log_delete(struct nl_sock *nlh, const struct nfnl_log *log)
    221 {
    222 	struct nl_msg *msg;
    223 	int err;
    224 
    225 	if ((err = nfnl_log_build_delete_request(log, &msg)) < 0)
    226 		return err;
    227 
    228 	return send_log_request(nlh, msg);
    229 }
    230 
    231 /** @} */
    232 
    233 static struct nl_cache_ops nfnl_log_ops = {
    234 	.co_name		= "netfilter/log",
    235 	.co_obj_ops		= &log_obj_ops,
    236 	.co_msgtypes		= {
    237 		END_OF_MSGTYPES_LIST,
    238 	},
    239 };
    240 
    241 static void __init log_init(void)
    242 {
    243 	nl_cache_mngt_register(&nfnl_log_ops);
    244 }
    245 
    246 static void __exit log_exit(void)
    247 {
    248 	nl_cache_mngt_unregister(&nfnl_log_ops);
    249 }
    250 
    251 /** @} */
    252