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 (at) suug.ch> 10 * Copyright (c) 2007 Philip Craig <philipc (at) snapgear.com> 11 * Copyright (c) 2007 Secure Computing Corporation 12 * Copyright (c) 2008 Patrick McHardy <kaber (at) 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-private/netlink.h> 26 #include <netlink/attr.h> 27 #include <netlink/netfilter/nfnl.h> 28 #include <netlink/netfilter/log_msg.h> 29 #include <byteswap.h> 30 31 #if __BYTE_ORDER == __BIG_ENDIAN 32 static uint64_t ntohll(uint64_t x) 33 { 34 return x; 35 } 36 #elif __BYTE_ORDER == __LITTLE_ENDIAN 37 static uint64_t ntohll(uint64_t x) 38 { 39 return bswap_64(x); 40 } 41 #endif 42 43 static struct nla_policy log_msg_policy[NFULA_MAX+1] = { 44 [NFULA_PACKET_HDR] = { 45 .minlen = sizeof(struct nfulnl_msg_packet_hdr) 46 }, 47 [NFULA_MARK] = { .type = NLA_U32 }, 48 [NFULA_TIMESTAMP] = { 49 .minlen = sizeof(struct nfulnl_msg_packet_timestamp) 50 }, 51 [NFULA_IFINDEX_INDEV] = { .type = NLA_U32 }, 52 [NFULA_IFINDEX_OUTDEV] = { .type = NLA_U32 }, 53 [NFULA_IFINDEX_PHYSINDEV] = { .type = NLA_U32 }, 54 [NFULA_IFINDEX_PHYSOUTDEV] = { .type = NLA_U32 }, 55 [NFULA_HWADDR] = { 56 .minlen = sizeof(struct nfulnl_msg_packet_hw) 57 }, 58 //[NFULA_PAYLOAD] 59 [NFULA_PREFIX] = { .type = NLA_STRING, }, 60 [NFULA_UID] = { .type = NLA_U32 }, 61 [NFULA_GID] = { .type = NLA_U32 }, 62 [NFULA_SEQ] = { .type = NLA_U32 }, 63 [NFULA_SEQ_GLOBAL] = { .type = NLA_U32 }, 64 }; 65 66 int nfnlmsg_log_msg_parse(struct nlmsghdr *nlh, struct nfnl_log_msg **result) 67 { 68 struct nfnl_log_msg *msg; 69 struct nlattr *tb[NFULA_MAX+1]; 70 struct nlattr *attr; 71 int err; 72 73 msg = nfnl_log_msg_alloc(); 74 if (!msg) 75 return -NLE_NOMEM; 76 77 msg->ce_msgtype = nlh->nlmsg_type; 78 79 err = nlmsg_parse(nlh, sizeof(struct nfgenmsg), tb, NFULA_MAX, 80 log_msg_policy); 81 if (err < 0) 82 goto errout; 83 84 nfnl_log_msg_set_family(msg, nfnlmsg_family(nlh)); 85 86 attr = tb[NFULA_PACKET_HDR]; 87 if (attr) { 88 struct nfulnl_msg_packet_hdr *hdr = nla_data(attr); 89 90 if (hdr->hw_protocol) 91 nfnl_log_msg_set_hwproto(msg, hdr->hw_protocol); 92 nfnl_log_msg_set_hook(msg, hdr->hook); 93 } 94 95 attr = tb[NFULA_MARK]; 96 if (attr) 97 nfnl_log_msg_set_mark(msg, ntohl(nla_get_u32(attr))); 98 99 attr = tb[NFULA_TIMESTAMP]; 100 if (attr) { 101 struct nfulnl_msg_packet_timestamp *timestamp = nla_data(attr); 102 struct timeval tv; 103 104 tv.tv_sec = ntohll(timestamp->sec); 105 tv.tv_usec = ntohll(timestamp->usec); 106 nfnl_log_msg_set_timestamp(msg, &tv); 107 } 108 109 attr = tb[NFULA_IFINDEX_INDEV]; 110 if (attr) 111 nfnl_log_msg_set_indev(msg, ntohl(nla_get_u32(attr))); 112 113 attr = tb[NFULA_IFINDEX_OUTDEV]; 114 if (attr) 115 nfnl_log_msg_set_outdev(msg, ntohl(nla_get_u32(attr))); 116 117 attr = tb[NFULA_IFINDEX_PHYSINDEV]; 118 if (attr) 119 nfnl_log_msg_set_physindev(msg, ntohl(nla_get_u32(attr))); 120 121 attr = tb[NFULA_IFINDEX_PHYSOUTDEV]; 122 if (attr) 123 nfnl_log_msg_set_physoutdev(msg, ntohl(nla_get_u32(attr))); 124 125 attr = tb[NFULA_HWADDR]; 126 if (attr) { 127 struct nfulnl_msg_packet_hw *hw = nla_data(attr); 128 129 nfnl_log_msg_set_hwaddr(msg, hw->hw_addr, ntohs(hw->hw_addrlen)); 130 } 131 132 attr = tb[NFULA_PAYLOAD]; 133 if (attr) { 134 err = nfnl_log_msg_set_payload(msg, nla_data(attr), nla_len(attr)); 135 if (err < 0) 136 goto errout; 137 } 138 139 attr = tb[NFULA_PREFIX]; 140 if (attr) { 141 err = nfnl_log_msg_set_prefix(msg, nla_data(attr)); 142 if (err < 0) 143 goto errout; 144 } 145 146 attr = tb[NFULA_UID]; 147 if (attr) 148 nfnl_log_msg_set_uid(msg, ntohl(nla_get_u32(attr))); 149 150 attr = tb[NFULA_GID]; 151 if (attr) 152 nfnl_log_msg_set_gid(msg, ntohl(nla_get_u32(attr))); 153 154 attr = tb[NFULA_SEQ]; 155 if (attr) 156 nfnl_log_msg_set_seq(msg, ntohl(nla_get_u32(attr))); 157 158 attr = tb[NFULA_SEQ_GLOBAL]; 159 if (attr) 160 nfnl_log_msg_set_seq_global(msg, ntohl(nla_get_u32(attr))); 161 162 *result = msg; 163 return 0; 164 165 errout: 166 nfnl_log_msg_put(msg); 167 return err; 168 } 169 170 static int log_msg_parser(struct nl_cache_ops *ops, struct sockaddr_nl *who, 171 struct nlmsghdr *nlh, struct nl_parser_param *pp) 172 { 173 struct nfnl_log_msg *msg; 174 int err; 175 176 if ((err = nfnlmsg_log_msg_parse(nlh, &msg)) < 0) 177 return err; 178 179 err = pp->pp_cb((struct nl_object *) msg, pp); 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)) 187 static 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 199 static void __init log_msg_init(void) 200 { 201 nl_cache_mngt_register(&nfnl_log_msg_ops); 202 } 203 204 static void __exit log_msg_exit(void) 205 { 206 nl_cache_mngt_unregister(&nfnl_log_msg_ops); 207 } 208 209 /** @} */ 210