1/* 2 * lib/netfilter/log_msg.c Netfilter Log Message 3 * 4 * This library is free software; you can redistribute it and/or 5 * modify it under the terms of the GNU Lesser General Public 6 * License as published by the Free Software Foundation version 2.1 7 * of the License. 8 * 9 * Copyright (c) 2003-2008 Thomas Graf <tgraf@suug.ch> 10 * Copyright (c) 2007 Philip Craig <philipc@snapgear.com> 11 * Copyright (c) 2007 Secure Computing Corporation 12 * Copyright (c) 2008 Patrick McHardy <kaber@trash.net> 13 */ 14 15/** 16 * @ingroup nfnl 17 * @defgroup log Log 18 * @brief 19 * @{ 20 */ 21 22#include <sys/types.h> 23#include <linux/netfilter/nfnetlink_log.h> 24 25#include <netlink-local.h> 26#include <netlink/attr.h> 27#include <netlink/netfilter/nfnl.h> 28#include <netlink/netfilter/log_msg.h> 29 30#if __BYTE_ORDER == __BIG_ENDIAN 31static uint64_t ntohll(uint64_t x) 32{ 33 return x; 34} 35#elif __BYTE_ORDER == __LITTLE_ENDIAN 36static uint64_t ntohll(uint64_t x) 37{ 38 return __bswap_64(x); 39} 40#endif 41 42static struct nla_policy log_msg_policy[NFULA_MAX+1] = { 43 [NFULA_PACKET_HDR] = { 44 .minlen = sizeof(struct nfulnl_msg_packet_hdr) 45 }, 46 [NFULA_MARK] = { .type = NLA_U32 }, 47 [NFULA_TIMESTAMP] = { 48 .minlen = sizeof(struct nfulnl_msg_packet_timestamp) 49 }, 50 [NFULA_IFINDEX_INDEV] = { .type = NLA_U32 }, 51 [NFULA_IFINDEX_OUTDEV] = { .type = NLA_U32 }, 52 [NFULA_IFINDEX_PHYSINDEV] = { .type = NLA_U32 }, 53 [NFULA_IFINDEX_PHYSOUTDEV] = { .type = NLA_U32 }, 54 [NFULA_HWADDR] = { 55 .minlen = sizeof(struct nfulnl_msg_packet_hw) 56 }, 57 //[NFULA_PAYLOAD] 58 [NFULA_PREFIX] = { .type = NLA_STRING, }, 59 [NFULA_UID] = { .type = NLA_U32 }, 60 [NFULA_GID] = { .type = NLA_U32 }, 61 [NFULA_SEQ] = { .type = NLA_U32 }, 62 [NFULA_SEQ_GLOBAL] = { .type = NLA_U32 }, 63}; 64 65int nfnlmsg_log_msg_parse(struct nlmsghdr *nlh, struct nfnl_log_msg **result) 66{ 67 struct nfnl_log_msg *msg; 68 struct nlattr *tb[NFULA_MAX+1]; 69 struct nlattr *attr; 70 int err; 71 72 msg = nfnl_log_msg_alloc(); 73 if (!msg) 74 return -NLE_NOMEM; 75 76 msg->ce_msgtype = nlh->nlmsg_type; 77 78 err = nlmsg_parse(nlh, sizeof(struct nfgenmsg), tb, NFULA_MAX, 79 log_msg_policy); 80 if (err < 0) 81 goto errout; 82 83 nfnl_log_msg_set_family(msg, nfnlmsg_family(nlh)); 84 85 attr = tb[NFULA_PACKET_HDR]; 86 if (attr) { 87 struct nfulnl_msg_packet_hdr *hdr = nla_data(attr); 88 89 if (hdr->hw_protocol) 90 nfnl_log_msg_set_hwproto(msg, hdr->hw_protocol); 91 nfnl_log_msg_set_hook(msg, hdr->hook); 92 } 93 94 attr = tb[NFULA_MARK]; 95 if (attr) 96 nfnl_log_msg_set_mark(msg, ntohl(nla_get_u32(attr))); 97 98 attr = tb[NFULA_TIMESTAMP]; 99 if (attr) { 100 struct nfulnl_msg_packet_timestamp *timestamp = nla_data(attr); 101 struct timeval tv; 102 103 tv.tv_sec = ntohll(timestamp->sec); 104 tv.tv_usec = ntohll(timestamp->usec); 105 nfnl_log_msg_set_timestamp(msg, &tv); 106 } 107 108 attr = tb[NFULA_IFINDEX_INDEV]; 109 if (attr) 110 nfnl_log_msg_set_indev(msg, ntohl(nla_get_u32(attr))); 111 112 attr = tb[NFULA_IFINDEX_OUTDEV]; 113 if (attr) 114 nfnl_log_msg_set_outdev(msg, ntohl(nla_get_u32(attr))); 115 116 attr = tb[NFULA_IFINDEX_PHYSINDEV]; 117 if (attr) 118 nfnl_log_msg_set_physindev(msg, ntohl(nla_get_u32(attr))); 119 120 attr = tb[NFULA_IFINDEX_PHYSOUTDEV]; 121 if (attr) 122 nfnl_log_msg_set_physoutdev(msg, ntohl(nla_get_u32(attr))); 123 124 attr = tb[NFULA_HWADDR]; 125 if (attr) { 126 struct nfulnl_msg_packet_hw *hw = nla_data(attr); 127 128 nfnl_log_msg_set_hwaddr(msg, hw->hw_addr, ntohs(hw->hw_addrlen)); 129 } 130 131 attr = tb[NFULA_PAYLOAD]; 132 if (attr) { 133 err = nfnl_log_msg_set_payload(msg, nla_data(attr), nla_len(attr)); 134 if (err < 0) 135 goto errout; 136 } 137 138 attr = tb[NFULA_PREFIX]; 139 if (attr) { 140 err = nfnl_log_msg_set_prefix(msg, nla_data(attr)); 141 if (err < 0) 142 goto errout; 143 } 144 145 attr = tb[NFULA_UID]; 146 if (attr) 147 nfnl_log_msg_set_uid(msg, ntohl(nla_get_u32(attr))); 148 149 attr = tb[NFULA_GID]; 150 if (attr) 151 nfnl_log_msg_set_gid(msg, ntohl(nla_get_u32(attr))); 152 153 attr = tb[NFULA_SEQ]; 154 if (attr) 155 nfnl_log_msg_set_seq(msg, ntohl(nla_get_u32(attr))); 156 157 attr = tb[NFULA_SEQ_GLOBAL]; 158 if (attr) 159 nfnl_log_msg_set_seq_global(msg, ntohl(nla_get_u32(attr))); 160 161 *result = msg; 162 return 0; 163 164errout: 165 nfnl_log_msg_put(msg); 166 return err; 167} 168 169static int log_msg_parser(struct nl_cache_ops *ops, struct sockaddr_nl *who, 170 struct nlmsghdr *nlh, struct nl_parser_param *pp) 171{ 172 struct nfnl_log_msg *msg; 173 int err; 174 175 if ((err = nfnlmsg_log_msg_parse(nlh, &msg)) < 0) 176 goto errout; 177 178 err = pp->pp_cb((struct nl_object *) msg, pp); 179errout: 180 nfnl_log_msg_put(msg); 181 return err; 182} 183 184/** @} */ 185 186#define NFNLMSG_LOG_TYPE(type) NFNLMSG_TYPE(NFNL_SUBSYS_ULOG, (type)) 187static struct nl_cache_ops nfnl_log_msg_ops = { 188 .co_name = "netfilter/log_msg", 189 .co_hdrsize = NFNL_HDRLEN, 190 .co_msgtypes = { 191 { NFNLMSG_LOG_TYPE(NFULNL_MSG_PACKET), NL_ACT_NEW, "new" }, 192 END_OF_MSGTYPES_LIST, 193 }, 194 .co_protocol = NETLINK_NETFILTER, 195 .co_msg_parser = log_msg_parser, 196 .co_obj_ops = &log_msg_obj_ops, 197}; 198 199static void __init log_msg_init(void) 200{ 201 nl_cache_mngt_register(&nfnl_log_msg_ops); 202} 203 204static void __exit log_msg_exit(void) 205{ 206 nl_cache_mngt_unregister(&nfnl_log_msg_ops); 207} 208 209/** @} */ 210