libnl
3.2.3
|
00001 /* 00002 * lib/netfilter/log.c Netfilter Log 00003 * 00004 * This library is free software; you can redistribute it and/or 00005 * modify it under the terms of the GNU Lesser General Public 00006 * License as published by the Free Software Foundation version 2.1 00007 * of the License. 00008 * 00009 * Copyright (c) 2003-2008 Thomas Graf <tgraf@suug.ch> 00010 * Copyright (c) 2007 Philip Craig <philipc@snapgear.com> 00011 * Copyright (c) 2007 Secure Computing Corporation 00012 */ 00013 00014 /** 00015 * @ingroup nfnl 00016 * @defgroup log Log 00017 * @brief 00018 * @{ 00019 */ 00020 00021 #include <sys/types.h> 00022 #include <linux/netfilter/nfnetlink_log.h> 00023 00024 #include <netlink-local.h> 00025 #include <netlink/attr.h> 00026 #include <netlink/netfilter/nfnl.h> 00027 #include <netlink/netfilter/log.h> 00028 00029 /** 00030 * @name Log Commands 00031 * @{ 00032 */ 00033 00034 static int build_log_cmd_request(uint8_t family, uint16_t queuenum, 00035 uint8_t command, struct nl_msg **result) 00036 { 00037 struct nl_msg *msg; 00038 struct nfulnl_msg_config_cmd cmd; 00039 00040 msg = nfnlmsg_alloc_simple(NFNL_SUBSYS_ULOG, NFULNL_MSG_CONFIG, 0, 00041 family, queuenum); 00042 if (msg == NULL) 00043 return -NLE_NOMEM; 00044 00045 cmd.command = command; 00046 if (nla_put(msg, NFULA_CFG_CMD, sizeof(cmd), &cmd) < 0) 00047 goto nla_put_failure; 00048 00049 *result = msg; 00050 return 0; 00051 00052 nla_put_failure: 00053 nlmsg_free(msg); 00054 return -NLE_MSGSIZE; 00055 } 00056 00057 static int send_log_request(struct nl_sock *sk, struct nl_msg *msg) 00058 { 00059 int err; 00060 00061 err = nl_send_auto_complete(sk, msg); 00062 nlmsg_free(msg); 00063 if (err < 0) 00064 return err; 00065 00066 return wait_for_ack(sk); 00067 } 00068 00069 int nfnl_log_build_pf_bind(uint8_t pf, struct nl_msg **result) 00070 { 00071 return build_log_cmd_request(pf, 0, NFULNL_CFG_CMD_PF_BIND, result); 00072 } 00073 00074 int nfnl_log_pf_bind(struct nl_sock *nlh, uint8_t pf) 00075 { 00076 struct nl_msg *msg; 00077 int err; 00078 00079 if ((err = nfnl_log_build_pf_bind(pf, &msg)) < 0) 00080 return err; 00081 00082 return send_log_request(nlh, msg); 00083 } 00084 00085 int nfnl_log_build_pf_unbind(uint8_t pf, struct nl_msg **result) 00086 { 00087 return build_log_cmd_request(pf, 0, NFULNL_CFG_CMD_PF_UNBIND, result); 00088 } 00089 00090 int nfnl_log_pf_unbind(struct nl_sock *nlh, uint8_t pf) 00091 { 00092 struct nl_msg *msg; 00093 int err; 00094 00095 if ((err = nfnl_log_build_pf_unbind(pf, &msg)) < 0) 00096 return err; 00097 00098 return send_log_request(nlh, msg); 00099 } 00100 00101 static int nfnl_log_build_request(const struct nfnl_log *log, 00102 struct nl_msg **result) 00103 { 00104 struct nl_msg *msg; 00105 00106 if (!nfnl_log_test_group(log)) 00107 return -NLE_MISSING_ATTR; 00108 00109 msg = nfnlmsg_alloc_simple(NFNL_SUBSYS_ULOG, NFULNL_MSG_CONFIG, 0, 00110 0, nfnl_log_get_group(log)); 00111 if (msg == NULL) 00112 return -NLE_NOMEM; 00113 00114 /* This sucks. The nfnetlink_log interface always expects both 00115 * parameters to be present. Needs to be done properly. 00116 */ 00117 if (nfnl_log_test_copy_mode(log)) { 00118 struct nfulnl_msg_config_mode mode; 00119 00120 switch (nfnl_log_get_copy_mode(log)) { 00121 case NFNL_LOG_COPY_NONE: 00122 mode.copy_mode = NFULNL_COPY_NONE; 00123 break; 00124 case NFNL_LOG_COPY_META: 00125 mode.copy_mode = NFULNL_COPY_META; 00126 break; 00127 case NFNL_LOG_COPY_PACKET: 00128 mode.copy_mode = NFULNL_COPY_PACKET; 00129 break; 00130 } 00131 mode.copy_range = htonl(nfnl_log_get_copy_range(log)); 00132 mode._pad = 0; 00133 00134 if (nla_put(msg, NFULA_CFG_MODE, sizeof(mode), &mode) < 0) 00135 goto nla_put_failure; 00136 } 00137 00138 if (nfnl_log_test_flush_timeout(log) && 00139 nla_put_u32(msg, NFULA_CFG_TIMEOUT, 00140 htonl(nfnl_log_get_flush_timeout(log))) < 0) 00141 goto nla_put_failure; 00142 00143 if (nfnl_log_test_alloc_size(log) && 00144 nla_put_u32(msg, NFULA_CFG_NLBUFSIZ, 00145 htonl(nfnl_log_get_alloc_size(log))) < 0) 00146 goto nla_put_failure; 00147 00148 if (nfnl_log_test_queue_threshold(log) && 00149 nla_put_u32(msg, NFULA_CFG_QTHRESH, 00150 htonl(nfnl_log_get_queue_threshold(log))) < 0) 00151 goto nla_put_failure; 00152 00153 *result = msg; 00154 return 0; 00155 00156 nla_put_failure: 00157 nlmsg_free(msg); 00158 return -NLE_MSGSIZE; 00159 } 00160 00161 int nfnl_log_build_create_request(const struct nfnl_log *log, 00162 struct nl_msg **result) 00163 { 00164 struct nfulnl_msg_config_cmd cmd; 00165 int err; 00166 00167 if ((err = nfnl_log_build_request(log, result)) < 0) 00168 return err; 00169 00170 cmd.command = NFULNL_CFG_CMD_BIND; 00171 00172 if (nla_put(*result, NFULA_CFG_CMD, sizeof(cmd), &cmd) < 0) 00173 goto nla_put_failure; 00174 00175 return 0; 00176 00177 nla_put_failure: 00178 nlmsg_free(*result); 00179 return -NLE_MSGSIZE; 00180 } 00181 00182 int nfnl_log_create(struct nl_sock *nlh, const struct nfnl_log *log) 00183 { 00184 struct nl_msg *msg; 00185 int err; 00186 00187 if ((err = nfnl_log_build_create_request(log, &msg)) < 0) 00188 return err; 00189 00190 return send_log_request(nlh, msg); 00191 } 00192 00193 int nfnl_log_build_change_request(const struct nfnl_log *log, 00194 struct nl_msg **result) 00195 { 00196 return nfnl_log_build_request(log, result); 00197 } 00198 00199 int nfnl_log_change(struct nl_sock *nlh, const struct nfnl_log *log) 00200 { 00201 struct nl_msg *msg; 00202 int err; 00203 00204 if ((err = nfnl_log_build_change_request(log, &msg)) < 0) 00205 return err; 00206 00207 return send_log_request(nlh, msg); 00208 } 00209 00210 int nfnl_log_build_delete_request(const struct nfnl_log *log, 00211 struct nl_msg **result) 00212 { 00213 if (!nfnl_log_test_group(log)) 00214 return -NLE_MISSING_ATTR; 00215 00216 return build_log_cmd_request(0, nfnl_log_get_group(log), 00217 NFULNL_CFG_CMD_UNBIND, result); 00218 } 00219 00220 int nfnl_log_delete(struct nl_sock *nlh, const struct nfnl_log *log) 00221 { 00222 struct nl_msg *msg; 00223 int err; 00224 00225 if ((err = nfnl_log_build_delete_request(log, &msg)) < 0) 00226 return err; 00227 00228 return send_log_request(nlh, msg); 00229 } 00230 00231 /** @} */ 00232 00233 static struct nl_cache_ops nfnl_log_ops = { 00234 .co_name = "netfilter/log", 00235 .co_obj_ops = &log_obj_ops, 00236 .co_msgtypes = { 00237 END_OF_MSGTYPES_LIST, 00238 }, 00239 }; 00240 00241 static void __init log_init(void) 00242 { 00243 nl_cache_mngt_register(&nfnl_log_ops); 00244 } 00245 00246 static void __exit log_exit(void) 00247 { 00248 nl_cache_mngt_unregister(&nfnl_log_ops); 00249 } 00250 00251 /** @} */