libnl 1.1
|
00001 /* 00002 * lib/netfilter/log.c Netfilter Log 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-2006 Thomas Graf <tgraf@suug.ch> 00010 * Copyright (c) 2007 Philip Craig <philipc@snapgear.com> 00011 * Copyright (c) 2007 Secure Computing Corporation 00012 */ 00013 00014 /** 00015 * @ingroup nfnl 00016 * @defgroup log Log 00017 * @brief 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 //[NFULA_PAYLOAD] 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 * @name Log Commands 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 /** @} */