libnl  3.2.3
/build/buildd/libnl3-3.2.3/lib/netfilter/log_msg.c
00001 /*
00002  * lib/netfilter/log_msg.c      Netfilter Log Message
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  * Copyright (c) 2008 Patrick McHardy <kaber@trash.net>
00013  */
00014 
00015 /**
00016  * @ingroup nfnl
00017  * @defgroup log Log
00018  * @brief
00019  * @{
00020  */
00021 
00022 #include <sys/types.h>
00023 #include <linux/netfilter/nfnetlink_log.h>
00024 
00025 #include <netlink-local.h>
00026 #include <netlink/attr.h>
00027 #include <netlink/netfilter/nfnl.h>
00028 #include <netlink/netfilter/log_msg.h>
00029 
00030 #if __BYTE_ORDER == __BIG_ENDIAN
00031 static uint64_t ntohll(uint64_t x)
00032 {
00033         return x;
00034 }
00035 #elif __BYTE_ORDER == __LITTLE_ENDIAN
00036 static uint64_t ntohll(uint64_t x)
00037 {
00038         return __bswap_64(x);
00039 }
00040 #endif
00041 
00042 static struct nla_policy log_msg_policy[NFULA_MAX+1] = {
00043         [NFULA_PACKET_HDR]              = {
00044                 .minlen = sizeof(struct nfulnl_msg_packet_hdr)
00045         },
00046         [NFULA_MARK]                    = { .type = NLA_U32 },
00047         [NFULA_TIMESTAMP]               = {
00048                 .minlen = sizeof(struct nfulnl_msg_packet_timestamp)
00049         },
00050         [NFULA_IFINDEX_INDEV]           = { .type = NLA_U32 },
00051         [NFULA_IFINDEX_OUTDEV]          = { .type = NLA_U32 },
00052         [NFULA_IFINDEX_PHYSINDEV]       = { .type = NLA_U32 },
00053         [NFULA_IFINDEX_PHYSOUTDEV]      = { .type = NLA_U32 },
00054         [NFULA_HWADDR]                  = {
00055                 .minlen = sizeof(struct nfulnl_msg_packet_hw)
00056         },
00057         //[NFULA_PAYLOAD]
00058         [NFULA_PREFIX]                  = { .type = NLA_STRING, },
00059         [NFULA_UID]                     = { .type = NLA_U32 },
00060         [NFULA_GID]                     = { .type = NLA_U32 },
00061         [NFULA_SEQ]                     = { .type = NLA_U32 },
00062         [NFULA_SEQ_GLOBAL]              = { .type = NLA_U32 },
00063 };
00064 
00065 int nfnlmsg_log_msg_parse(struct nlmsghdr *nlh, struct nfnl_log_msg **result)
00066 {
00067         struct nfnl_log_msg *msg;
00068         struct nlattr *tb[NFULA_MAX+1];
00069         struct nlattr *attr;
00070         int err;
00071 
00072         msg = nfnl_log_msg_alloc();
00073         if (!msg)
00074                 return -NLE_NOMEM;
00075 
00076         msg->ce_msgtype = nlh->nlmsg_type;
00077 
00078         err = nlmsg_parse(nlh, sizeof(struct nfgenmsg), tb, NFULA_MAX,
00079                           log_msg_policy);
00080         if (err < 0)
00081                 goto errout;
00082 
00083         nfnl_log_msg_set_family(msg, 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                 if (hdr->hw_protocol)
00090                         nfnl_log_msg_set_hwproto(msg, hdr->hw_protocol);
00091                 nfnl_log_msg_set_hook(msg, hdr->hook);
00092         }
00093 
00094         attr = tb[NFULA_MARK];
00095         if (attr)
00096                 nfnl_log_msg_set_mark(msg, ntohl(nla_get_u32(attr)));
00097 
00098         attr = tb[NFULA_TIMESTAMP];
00099         if (attr) {
00100                 struct nfulnl_msg_packet_timestamp *timestamp = nla_data(attr);
00101                 struct timeval tv;
00102 
00103                 tv.tv_sec = ntohll(timestamp->sec);
00104                 tv.tv_usec = ntohll(timestamp->usec);
00105                 nfnl_log_msg_set_timestamp(msg, &tv);
00106         }
00107 
00108         attr = tb[NFULA_IFINDEX_INDEV];
00109         if (attr)
00110                 nfnl_log_msg_set_indev(msg, ntohl(nla_get_u32(attr)));
00111 
00112         attr = tb[NFULA_IFINDEX_OUTDEV];
00113         if (attr)
00114                 nfnl_log_msg_set_outdev(msg, ntohl(nla_get_u32(attr)));
00115 
00116         attr = tb[NFULA_IFINDEX_PHYSINDEV];
00117         if (attr)
00118                 nfnl_log_msg_set_physindev(msg, ntohl(nla_get_u32(attr)));
00119 
00120         attr = tb[NFULA_IFINDEX_PHYSOUTDEV];
00121         if (attr)
00122                 nfnl_log_msg_set_physoutdev(msg, ntohl(nla_get_u32(attr)));
00123 
00124         attr = tb[NFULA_HWADDR];
00125         if (attr) {
00126                 struct nfulnl_msg_packet_hw *hw = nla_data(attr);
00127 
00128                 nfnl_log_msg_set_hwaddr(msg, hw->hw_addr, ntohs(hw->hw_addrlen));
00129         }
00130 
00131         attr = tb[NFULA_PAYLOAD];
00132         if (attr) {
00133                 err = nfnl_log_msg_set_payload(msg, nla_data(attr), nla_len(attr));
00134                 if (err < 0)
00135                         goto errout;
00136         }
00137 
00138         attr = tb[NFULA_PREFIX];
00139         if (attr) {
00140                 err = nfnl_log_msg_set_prefix(msg, nla_data(attr));
00141                 if (err < 0)
00142                         goto errout;
00143         }
00144 
00145         attr = tb[NFULA_UID];
00146         if (attr)
00147                 nfnl_log_msg_set_uid(msg, ntohl(nla_get_u32(attr)));
00148 
00149         attr = tb[NFULA_GID];
00150         if (attr)
00151                 nfnl_log_msg_set_gid(msg, ntohl(nla_get_u32(attr)));
00152 
00153         attr = tb[NFULA_SEQ];
00154         if (attr)
00155                 nfnl_log_msg_set_seq(msg, ntohl(nla_get_u32(attr)));
00156 
00157         attr = tb[NFULA_SEQ_GLOBAL];
00158         if (attr)
00159                 nfnl_log_msg_set_seq_global(msg, ntohl(nla_get_u32(attr)));
00160 
00161         *result = msg;
00162         return 0;
00163 
00164 errout:
00165         nfnl_log_msg_put(msg);
00166         return err;
00167 }
00168 
00169 static int log_msg_parser(struct nl_cache_ops *ops, struct sockaddr_nl *who,
00170                           struct nlmsghdr *nlh, struct nl_parser_param *pp)
00171 {
00172         struct nfnl_log_msg *msg;
00173         int err;
00174 
00175         if ((err = nfnlmsg_log_msg_parse(nlh, &msg)) < 0)
00176                 goto errout;
00177 
00178         err = pp->pp_cb((struct nl_object *) msg, pp);
00179 errout:
00180         nfnl_log_msg_put(msg);
00181         return err;
00182 }
00183 
00184 /** @} */
00185 
00186 #define NFNLMSG_LOG_TYPE(type) NFNLMSG_TYPE(NFNL_SUBSYS_ULOG, (type))
00187 static struct nl_cache_ops nfnl_log_msg_ops = {
00188         .co_name                = "netfilter/log_msg",
00189         .co_hdrsize             = NFNL_HDRLEN,
00190         .co_msgtypes            = {
00191                 { NFNLMSG_LOG_TYPE(NFULNL_MSG_PACKET), NL_ACT_NEW, "new" },
00192                 END_OF_MSGTYPES_LIST,
00193         },
00194         .co_protocol            = NETLINK_NETFILTER,
00195         .co_msg_parser          = log_msg_parser,
00196         .co_obj_ops             = &log_msg_obj_ops,
00197 };
00198 
00199 static void __init log_msg_init(void)
00200 {
00201         nl_cache_mngt_register(&nfnl_log_msg_ops);
00202 }
00203 
00204 static void __exit log_msg_exit(void)
00205 {
00206         nl_cache_mngt_unregister(&nfnl_log_msg_ops);
00207 }
00208 
00209 /** @} */