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