log.c

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 /** @} */