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