log.c revision 1155370f520cb64657e25153255cf7dc1424317f
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@suug.ch> 10 * Copyright (c) 2007 Philip Craig <philipc@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-local.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 34static 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 52nla_put_failure: 53 nlmsg_free(msg); 54 return -NLE_MSGSIZE; 55} 56 57static 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 nl_wait_for_ack(sk); 67} 68 69int 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 74int 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 85int 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 90int 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 101static 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 156nla_put_failure: 157 nlmsg_free(msg); 158 return -NLE_MSGSIZE; 159} 160 161int 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 177nla_put_failure: 178 nlmsg_free(*result); 179 return -NLE_MSGSIZE; 180} 181 182int 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 193int 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 199int 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 210int 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 220int 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 233static 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 241static void __init log_init(void) 242{ 243 nl_cache_mngt_register(&nfnl_log_ops); 244} 245 246static void __exit log_exit(void) 247{ 248 nl_cache_mngt_unregister(&nfnl_log_ops); 249} 250 251/** @} */ 252