00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
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
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
00115
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