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 static struct nl_cache_ops nfnl_log_ops;
00030
00031 #if __BYTE_ORDER == __BIG_ENDIAN
00032 static uint64_t ntohll(uint64_t x)
00033 {
00034 return x;
00035 }
00036 #elif __BYTE_ORDER == __LITTLE_ENDIAN
00037 static uint64_t ntohll(uint64_t x)
00038 {
00039 return __bswap_64(x);
00040 }
00041 #endif
00042
00043 static struct nla_policy log_policy[NFULA_MAX+1] = {
00044 [NFULA_PACKET_HDR] = {
00045 .minlen = sizeof(struct nfulnl_msg_packet_hdr)
00046 },
00047 [NFULA_MARK] = { .type = NLA_U32 },
00048 [NFULA_TIMESTAMP] = {
00049 .minlen = sizeof(struct nfulnl_msg_packet_timestamp)
00050 },
00051 [NFULA_IFINDEX_INDEV] = { .type = NLA_U32 },
00052 [NFULA_IFINDEX_OUTDEV] = { .type = NLA_U32 },
00053 [NFULA_IFINDEX_PHYSINDEV] = { .type = NLA_U32 },
00054 [NFULA_IFINDEX_PHYSOUTDEV] = { .type = NLA_U32 },
00055 [NFULA_HWADDR] = {
00056 .minlen = sizeof(struct nfulnl_msg_packet_hw)
00057 },
00058
00059 [NFULA_PREFIX] = { .type = NLA_STRING, },
00060 [NFULA_UID] = { .type = NLA_U32 },
00061 [NFULA_SEQ] = { .type = NLA_U32 },
00062 [NFULA_SEQ_GLOBAL] = { .type = NLA_U32 },
00063 };
00064
00065 struct nfnl_log *nfnlmsg_log_parse(struct nlmsghdr *nlh)
00066 {
00067 struct nfnl_log *log;
00068 struct nlattr *tb[NFULA_MAX+1];
00069 struct nlattr *attr;
00070 int err;
00071
00072 log = nfnl_log_alloc();
00073 if (!log)
00074 return NULL;
00075
00076 log->ce_msgtype = nlh->nlmsg_type;
00077
00078 err = nlmsg_parse(nlh, sizeof(struct nfgenmsg), tb, NFULA_MAX,
00079 log_policy);
00080 if (err < 0)
00081 goto errout;
00082
00083 nfnl_log_set_family(log, nfnlmsg_family(nlh));
00084
00085 attr = tb[NFULA_PACKET_HDR];
00086 if (attr) {
00087 struct nfulnl_msg_packet_hdr *hdr = nla_data(attr);
00088
00089 nfnl_log_set_hwproto(log, hdr->hw_protocol);
00090 nfnl_log_set_hook(log, hdr->hook);
00091 }
00092
00093 attr = tb[NFULA_MARK];
00094 if (attr)
00095 nfnl_log_set_mark(log, ntohl(nla_get_u32(attr)));
00096
00097 attr = tb[NFULA_TIMESTAMP];
00098 if (attr) {
00099 struct nfulnl_msg_packet_timestamp *timestamp = nla_data(attr);
00100 struct timeval tv;
00101
00102 tv.tv_sec = ntohll(timestamp->sec);
00103 tv.tv_usec = ntohll(timestamp->usec);
00104 nfnl_log_set_timestamp(log, &tv);
00105 }
00106
00107 attr = tb[NFULA_IFINDEX_INDEV];
00108 if (attr)
00109 nfnl_log_set_indev(log, ntohl(nla_get_u32(attr)));
00110
00111 attr = tb[NFULA_IFINDEX_OUTDEV];
00112 if (attr)
00113 nfnl_log_set_outdev(log, ntohl(nla_get_u32(attr)));
00114
00115 attr = tb[NFULA_IFINDEX_PHYSINDEV];
00116 if (attr)
00117 nfnl_log_set_physindev(log, ntohl(nla_get_u32(attr)));
00118
00119 attr = tb[NFULA_IFINDEX_PHYSOUTDEV];
00120 if (attr)
00121 nfnl_log_set_physoutdev(log, ntohl(nla_get_u32(attr)));
00122
00123 attr = tb[NFULA_HWADDR];
00124 if (attr) {
00125 struct nfulnl_msg_packet_hw *hw = nla_data(attr);
00126
00127 nfnl_log_set_hwaddr(log, hw->hw_addr, ntohs(hw->hw_addrlen));
00128 }
00129
00130 attr = tb[NFULA_PAYLOAD];
00131 if (attr) {
00132 err = nfnl_log_set_payload(log, nla_data(attr), nla_len(attr));
00133 if (err < 0)
00134 goto errout;
00135 }
00136
00137 attr = tb[NFULA_PREFIX];
00138 if (attr) {
00139 err = nfnl_log_set_prefix(log, nla_data(attr));
00140 if (err < 0)
00141 goto errout;
00142 }
00143
00144 attr = tb[NFULA_UID];
00145 if (attr)
00146 nfnl_log_set_uid(log, ntohl(nla_get_u32(attr)));
00147
00148 attr = tb[NFULA_SEQ];
00149 if (attr)
00150 nfnl_log_set_seq(log, ntohl(nla_get_u32(attr)));
00151
00152 attr = tb[NFULA_SEQ_GLOBAL];
00153 if (attr)
00154 nfnl_log_set_seq_global(log, ntohl(nla_get_u32(attr)));
00155
00156 return log;
00157
00158 errout:
00159 nfnl_log_put(log);
00160 return NULL;
00161 }
00162
00163 static int log_msg_parser(struct nl_cache_ops *ops, struct sockaddr_nl *who,
00164 struct nlmsghdr *nlh, struct nl_parser_param *pp)
00165 {
00166 struct nfnl_log *log;
00167 int err;
00168
00169 log = nfnlmsg_log_parse(nlh);
00170 if (log == NULL)
00171 goto errout_errno;
00172
00173 err = pp->pp_cb((struct nl_object *) log, pp);
00174 if (err < 0)
00175 goto errout;
00176
00177 err = P_ACCEPT;
00178
00179 errout:
00180 nfnl_log_put(log);
00181 return err;
00182
00183 errout_errno:
00184 err = nl_get_errno();
00185 goto errout;
00186 }
00187
00188
00189
00190
00191
00192
00193 static struct nl_msg *build_log_cmd_msg(uint8_t family, uint16_t queuenum,
00194 uint8_t command)
00195 {
00196 struct nl_msg *msg;
00197 struct nfulnl_msg_config_cmd cmd;
00198
00199 msg = nfnlmsg_alloc_simple(NFNL_SUBSYS_ULOG, NFULNL_MSG_CONFIG, 0,
00200 family, queuenum);
00201 if (msg == NULL)
00202 return NULL;
00203
00204 cmd.command = command;
00205 if (nla_put(msg, NFULA_CFG_CMD, sizeof(cmd), &cmd) < 0)
00206 goto nla_put_failure;
00207
00208 return msg;
00209
00210 nla_put_failure:
00211 nlmsg_free(msg);
00212 return NULL;
00213 }
00214
00215 static int send_log_msg(struct nl_handle *handle, struct nl_msg *msg)
00216 {
00217 int err;
00218
00219 err = nl_send_auto_complete(handle, msg);
00220 nlmsg_free(msg);
00221 if (err < 0)
00222 return err;
00223
00224 return nl_wait_for_ack(handle);
00225 }
00226
00227 struct nl_msg *nfnl_log_build_bind(uint16_t queuenum)
00228 {
00229 return build_log_cmd_msg(0, queuenum, NFULNL_CFG_CMD_BIND);
00230 }
00231
00232 int nfnl_log_bind(struct nl_handle *nlh, uint16_t queuenum)
00233 {
00234 struct nl_msg *msg;
00235
00236 msg = nfnl_log_build_bind(queuenum);
00237 if (!msg)
00238 return nl_get_errno();
00239
00240 return send_log_msg(nlh, msg);
00241 }
00242
00243 struct nl_msg *nfnl_log_build_unbind(uint16_t queuenum)
00244 {
00245 return build_log_cmd_msg(0, queuenum, NFULNL_CFG_CMD_UNBIND);
00246 }
00247
00248 int nfnl_log_unbind(struct nl_handle *nlh, uint16_t queuenum)
00249 {
00250 struct nl_msg *msg;
00251
00252 msg = nfnl_log_build_bind(queuenum);
00253 if (!msg)
00254 return nl_get_errno();
00255
00256 return send_log_msg(nlh, msg);
00257 }
00258
00259 struct nl_msg *nfnl_log_build_pf_bind(uint8_t pf)
00260 {
00261 return build_log_cmd_msg(pf, 0, NFULNL_CFG_CMD_PF_BIND);
00262 }
00263
00264 int nfnl_log_pf_bind(struct nl_handle *nlh, uint8_t pf)
00265 {
00266 struct nl_msg *msg;
00267
00268 msg = nfnl_log_build_pf_bind(pf);
00269 if (!msg)
00270 return nl_get_errno();
00271
00272 return send_log_msg(nlh, msg);
00273 }
00274
00275 struct nl_msg *nfnl_log_build_pf_unbind(uint8_t pf)
00276 {
00277 return build_log_cmd_msg(pf, 0, NFULNL_CFG_CMD_PF_UNBIND);
00278 }
00279
00280 int nfnl_log_pf_unbind(struct nl_handle *nlh, uint8_t pf)
00281 {
00282 struct nl_msg *msg;
00283
00284 msg = nfnl_log_build_pf_unbind(pf);
00285 if (!msg)
00286 return nl_get_errno();
00287
00288 return send_log_msg(nlh, msg);
00289 }
00290
00291 struct nl_msg *nfnl_log_build_mode(uint16_t queuenum, uint8_t copy_mode,
00292 uint32_t copy_range)
00293 {
00294 struct nl_msg *msg;
00295 struct nfulnl_msg_config_mode mode;
00296
00297 msg = nfnlmsg_alloc_simple(NFNL_SUBSYS_ULOG, NFULNL_MSG_CONFIG, 0,
00298 0, queuenum);
00299 if (msg == NULL)
00300 return NULL;
00301
00302 mode.copy_mode = copy_mode;
00303 mode.copy_range = htonl(copy_range);
00304 if (nla_put(msg, NFULA_CFG_MODE, sizeof(mode), &mode) < 0)
00305 goto nla_put_failure;
00306
00307 return msg;
00308
00309 nla_put_failure:
00310 nlmsg_free(msg);
00311 return NULL;
00312 }
00313
00314 int nfnl_log_set_mode(struct nl_handle *nlh, uint16_t queuenum,
00315 uint8_t copy_mode, uint32_t copy_range)
00316 {
00317 struct nl_msg *msg;
00318
00319 msg = nfnl_log_build_mode(queuenum, copy_mode, copy_range);
00320 if (!msg)
00321 return nl_get_errno();
00322 return send_log_msg(nlh, msg);
00323 }
00324
00325
00326
00327 #define NFNLMSG_LOG_TYPE(type) NFNLMSG_TYPE(NFNL_SUBSYS_ULOG, (type))
00328 static struct nl_cache_ops nfnl_log_ops = {
00329 .co_name = "netfilter/log",
00330 .co_hdrsize = NFNL_HDRLEN,
00331 .co_msgtypes = {
00332 { NFNLMSG_LOG_TYPE(NFULNL_MSG_PACKET), NL_ACT_NEW, "new" },
00333 END_OF_MSGTYPES_LIST,
00334 },
00335 .co_protocol = NETLINK_NETFILTER,
00336 .co_msg_parser = log_msg_parser,
00337 .co_obj_ops = &log_obj_ops,
00338 };
00339
00340 static void __init log_init(void)
00341 {
00342 nl_cache_mngt_register(&nfnl_log_ops);
00343 }
00344
00345 static void __exit log_exit(void)
00346 {
00347 nl_cache_mngt_unregister(&nfnl_log_ops);
00348 }
00349
00350