libnl
3.2.3
|
00001 /* 00002 * lib/netfilter/log_msg_obj.c Netfilter Log Object 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 */ 00013 00014 #include <netlink-local.h> 00015 #include <netlink/netfilter/nfnl.h> 00016 #include <netlink/netfilter/netfilter.h> 00017 #include <netlink/netfilter/log_msg.h> 00018 00019 /** @cond SKIP */ 00020 #define LOG_MSG_ATTR_FAMILY (1UL << 0) 00021 #define LOG_MSG_ATTR_HWPROTO (1UL << 1) 00022 #define LOG_MSG_ATTR_HOOK (1UL << 2) 00023 #define LOG_MSG_ATTR_MARK (1UL << 3) 00024 #define LOG_MSG_ATTR_TIMESTAMP (1UL << 4) 00025 #define LOG_MSG_ATTR_INDEV (1UL << 5) 00026 #define LOG_MSG_ATTR_OUTDEV (1UL << 6) 00027 #define LOG_MSG_ATTR_PHYSINDEV (1UL << 7) 00028 #define LOG_MSG_ATTR_PHYSOUTDEV (1UL << 8) 00029 #define LOG_MSG_ATTR_HWADDR (1UL << 9) 00030 #define LOG_MSG_ATTR_PAYLOAD (1UL << 10) 00031 #define LOG_MSG_ATTR_PREFIX (1UL << 11) 00032 #define LOG_MSG_ATTR_UID (1UL << 12) 00033 #define LOG_MSG_ATTR_GID (1UL << 13) 00034 #define LOG_MSG_ATTR_SEQ (1UL << 14) 00035 #define LOG_MSG_ATTR_SEQ_GLOBAL (1UL << 15) 00036 /** @endcond */ 00037 00038 static void log_msg_free_data(struct nl_object *c) 00039 { 00040 struct nfnl_log_msg *msg = (struct nfnl_log_msg *) c; 00041 00042 if (msg == NULL) 00043 return; 00044 00045 free(msg->log_msg_payload); 00046 free(msg->log_msg_prefix); 00047 } 00048 00049 static int log_msg_clone(struct nl_object *_dst, struct nl_object *_src) 00050 { 00051 struct nfnl_log_msg *dst = (struct nfnl_log_msg *) _dst; 00052 struct nfnl_log_msg *src = (struct nfnl_log_msg *) _src; 00053 int err; 00054 00055 if (src->log_msg_payload) { 00056 err = nfnl_log_msg_set_payload(dst, src->log_msg_payload, 00057 src->log_msg_payload_len); 00058 if (err < 0) 00059 goto errout; 00060 } 00061 00062 if (src->log_msg_prefix) { 00063 err = nfnl_log_msg_set_prefix(dst, src->log_msg_prefix); 00064 if (err < 0) 00065 goto errout; 00066 } 00067 00068 return 0; 00069 errout: 00070 return err; 00071 } 00072 00073 static void log_msg_dump(struct nl_object *a, struct nl_dump_params *p) 00074 { 00075 struct nfnl_log_msg *msg = (struct nfnl_log_msg *) a; 00076 struct nl_cache *link_cache; 00077 char buf[64]; 00078 00079 link_cache = nl_cache_mngt_require("route/link"); 00080 00081 nl_new_line(p); 00082 00083 if (msg->ce_mask & LOG_MSG_ATTR_PREFIX) 00084 nl_dump(p, "%s", msg->log_msg_prefix); 00085 00086 if (msg->ce_mask & LOG_MSG_ATTR_INDEV) { 00087 if (link_cache) 00088 nl_dump(p, "IN=%s ", 00089 rtnl_link_i2name(link_cache, 00090 msg->log_msg_indev, 00091 buf, sizeof(buf))); 00092 else 00093 nl_dump(p, "IN=%d ", msg->log_msg_indev); 00094 } 00095 00096 if (msg->ce_mask & LOG_MSG_ATTR_PHYSINDEV) { 00097 if (link_cache) 00098 nl_dump(p, "PHYSIN=%s ", 00099 rtnl_link_i2name(link_cache, 00100 msg->log_msg_physindev, 00101 buf, sizeof(buf))); 00102 else 00103 nl_dump(p, "IN=%d ", msg->log_msg_physindev); 00104 } 00105 00106 if (msg->ce_mask & LOG_MSG_ATTR_OUTDEV) { 00107 if (link_cache) 00108 nl_dump(p, "OUT=%s ", 00109 rtnl_link_i2name(link_cache, 00110 msg->log_msg_outdev, 00111 buf, sizeof(buf))); 00112 else 00113 nl_dump(p, "OUT=%d ", msg->log_msg_outdev); 00114 } 00115 00116 if (msg->ce_mask & LOG_MSG_ATTR_PHYSOUTDEV) { 00117 if (link_cache) 00118 nl_dump(p, "PHYSOUT=%s ", 00119 rtnl_link_i2name(link_cache, 00120 msg->log_msg_physoutdev, 00121 buf, sizeof(buf))); 00122 else 00123 nl_dump(p, "PHYSOUT=%d ", msg->log_msg_physoutdev); 00124 } 00125 00126 if (msg->ce_mask & LOG_MSG_ATTR_HWADDR) { 00127 int i; 00128 00129 nl_dump(p, "MAC"); 00130 for (i = 0; i < msg->log_msg_hwaddr_len; i++) 00131 nl_dump(p, "%c%02x", i?':':'=', msg->log_msg_hwaddr[i]); 00132 nl_dump(p, " "); 00133 } 00134 00135 /* FIXME: parse the payload to get iptables LOG compatible format */ 00136 00137 if (msg->ce_mask & LOG_MSG_ATTR_FAMILY) 00138 nl_dump(p, "FAMILY=%s ", 00139 nl_af2str(msg->log_msg_family, buf, sizeof(buf))); 00140 00141 if (msg->ce_mask & LOG_MSG_ATTR_HWPROTO) 00142 nl_dump(p, "HWPROTO=%s ", 00143 nl_ether_proto2str(ntohs(msg->log_msg_hwproto), 00144 buf, sizeof(buf))); 00145 00146 if (msg->ce_mask & LOG_MSG_ATTR_HOOK) 00147 nl_dump(p, "HOOK=%s ", 00148 nfnl_inet_hook2str(msg->log_msg_hook, 00149 buf, sizeof(buf))); 00150 00151 if (msg->ce_mask & LOG_MSG_ATTR_MARK) 00152 nl_dump(p, "MARK=%u ", msg->log_msg_mark); 00153 00154 if (msg->ce_mask & LOG_MSG_ATTR_PAYLOAD) 00155 nl_dump(p, "PAYLOADLEN=%d ", msg->log_msg_payload_len); 00156 00157 if (msg->ce_mask & LOG_MSG_ATTR_UID) 00158 nl_dump(p, "UID=%u ", msg->log_msg_uid); 00159 00160 if (msg->ce_mask & LOG_MSG_ATTR_GID) 00161 nl_dump(p, "GID=%u ", msg->log_msg_gid); 00162 00163 if (msg->ce_mask & LOG_MSG_ATTR_SEQ) 00164 nl_dump(p, "SEQ=%d ", msg->log_msg_seq); 00165 00166 if (msg->ce_mask & LOG_MSG_ATTR_SEQ_GLOBAL) 00167 nl_dump(p, "SEQGLOBAL=%d ", msg->log_msg_seq_global); 00168 00169 nl_dump(p, "\n"); 00170 } 00171 00172 /** 00173 * @name Allocation/Freeing 00174 * @{ 00175 */ 00176 00177 struct nfnl_log_msg *nfnl_log_msg_alloc(void) 00178 { 00179 return (struct nfnl_log_msg *) nl_object_alloc(&log_msg_obj_ops); 00180 } 00181 00182 void nfnl_log_msg_get(struct nfnl_log_msg *msg) 00183 { 00184 nl_object_get((struct nl_object *) msg); 00185 } 00186 00187 void nfnl_log_msg_put(struct nfnl_log_msg *msg) 00188 { 00189 nl_object_put((struct nl_object *) msg); 00190 } 00191 00192 /** @} */ 00193 00194 /** 00195 * @name Attributes 00196 * @{ 00197 */ 00198 00199 void nfnl_log_msg_set_family(struct nfnl_log_msg *msg, uint8_t family) 00200 { 00201 msg->log_msg_family = family; 00202 msg->ce_mask |= LOG_MSG_ATTR_FAMILY; 00203 } 00204 00205 uint8_t nfnl_log_msg_get_family(const struct nfnl_log_msg *msg) 00206 { 00207 if (msg->ce_mask & LOG_MSG_ATTR_FAMILY) 00208 return msg->log_msg_family; 00209 else 00210 return AF_UNSPEC; 00211 } 00212 00213 void nfnl_log_msg_set_hwproto(struct nfnl_log_msg *msg, uint16_t hwproto) 00214 { 00215 msg->log_msg_hwproto = hwproto; 00216 msg->ce_mask |= LOG_MSG_ATTR_HWPROTO; 00217 } 00218 00219 int nfnl_log_msg_test_hwproto(const struct nfnl_log_msg *msg) 00220 { 00221 return !!(msg->ce_mask & LOG_MSG_ATTR_HWPROTO); 00222 } 00223 00224 uint16_t nfnl_log_msg_get_hwproto(const struct nfnl_log_msg *msg) 00225 { 00226 return msg->log_msg_hwproto; 00227 } 00228 00229 void nfnl_log_msg_set_hook(struct nfnl_log_msg *msg, uint8_t hook) 00230 { 00231 msg->log_msg_hook = hook; 00232 msg->ce_mask |= LOG_MSG_ATTR_HOOK; 00233 } 00234 00235 int nfnl_log_msg_test_hook(const struct nfnl_log_msg *msg) 00236 { 00237 return !!(msg->ce_mask & LOG_MSG_ATTR_HOOK); 00238 } 00239 00240 uint8_t nfnl_log_msg_get_hook(const struct nfnl_log_msg *msg) 00241 { 00242 return msg->log_msg_hook; 00243 } 00244 00245 void nfnl_log_msg_set_mark(struct nfnl_log_msg *msg, uint32_t mark) 00246 { 00247 msg->log_msg_mark = mark; 00248 msg->ce_mask |= LOG_MSG_ATTR_MARK; 00249 } 00250 00251 int nfnl_log_msg_test_mark(const struct nfnl_log_msg *msg) 00252 { 00253 return !!(msg->ce_mask & LOG_MSG_ATTR_MARK); 00254 } 00255 00256 uint32_t nfnl_log_msg_get_mark(const struct nfnl_log_msg *msg) 00257 { 00258 return msg->log_msg_mark; 00259 } 00260 00261 void nfnl_log_msg_set_timestamp(struct nfnl_log_msg *msg, struct timeval *tv) 00262 { 00263 msg->log_msg_timestamp.tv_sec = tv->tv_sec; 00264 msg->log_msg_timestamp.tv_usec = tv->tv_usec; 00265 msg->ce_mask |= LOG_MSG_ATTR_TIMESTAMP; 00266 } 00267 00268 const struct timeval *nfnl_log_msg_get_timestamp(const struct nfnl_log_msg *msg) 00269 { 00270 if (!(msg->ce_mask & LOG_MSG_ATTR_TIMESTAMP)) 00271 return NULL; 00272 return &msg->log_msg_timestamp; 00273 } 00274 00275 void nfnl_log_msg_set_indev(struct nfnl_log_msg *msg, uint32_t indev) 00276 { 00277 msg->log_msg_indev = indev; 00278 msg->ce_mask |= LOG_MSG_ATTR_INDEV; 00279 } 00280 00281 uint32_t nfnl_log_msg_get_indev(const struct nfnl_log_msg *msg) 00282 { 00283 return msg->log_msg_indev; 00284 } 00285 00286 void nfnl_log_msg_set_outdev(struct nfnl_log_msg *msg, uint32_t outdev) 00287 { 00288 msg->log_msg_outdev = outdev; 00289 msg->ce_mask |= LOG_MSG_ATTR_OUTDEV; 00290 } 00291 00292 uint32_t nfnl_log_msg_get_outdev(const struct nfnl_log_msg *msg) 00293 { 00294 return msg->log_msg_outdev; 00295 } 00296 00297 void nfnl_log_msg_set_physindev(struct nfnl_log_msg *msg, uint32_t physindev) 00298 { 00299 msg->log_msg_physindev = physindev; 00300 msg->ce_mask |= LOG_MSG_ATTR_PHYSINDEV; 00301 } 00302 00303 uint32_t nfnl_log_msg_get_physindev(const struct nfnl_log_msg *msg) 00304 { 00305 return msg->log_msg_physindev; 00306 } 00307 00308 void nfnl_log_msg_set_physoutdev(struct nfnl_log_msg *msg, uint32_t physoutdev) 00309 { 00310 msg->log_msg_physoutdev = physoutdev; 00311 msg->ce_mask |= LOG_MSG_ATTR_PHYSOUTDEV; 00312 } 00313 00314 uint32_t nfnl_log_msg_get_physoutdev(const struct nfnl_log_msg *msg) 00315 { 00316 return msg->log_msg_physoutdev; 00317 } 00318 00319 void nfnl_log_msg_set_hwaddr(struct nfnl_log_msg *msg, uint8_t *hwaddr, int len) 00320 { 00321 if (len > sizeof(msg->log_msg_hwaddr)) 00322 len = sizeof(msg->log_msg_hwaddr); 00323 msg->log_msg_hwaddr_len = len; 00324 memcpy(msg->log_msg_hwaddr, hwaddr, len); 00325 msg->ce_mask |= LOG_MSG_ATTR_HWADDR; 00326 } 00327 00328 const uint8_t *nfnl_log_msg_get_hwaddr(const struct nfnl_log_msg *msg, int *len) 00329 { 00330 if (!(msg->ce_mask & LOG_MSG_ATTR_HWADDR)) { 00331 *len = 0; 00332 return NULL; 00333 } 00334 00335 *len = msg->log_msg_hwaddr_len; 00336 return msg->log_msg_hwaddr; 00337 } 00338 00339 int nfnl_log_msg_set_payload(struct nfnl_log_msg *msg, uint8_t *payload, int len) 00340 { 00341 free(msg->log_msg_payload); 00342 msg->log_msg_payload = malloc(len); 00343 if (!msg->log_msg_payload) 00344 return -NLE_NOMEM; 00345 00346 memcpy(msg->log_msg_payload, payload, len); 00347 msg->log_msg_payload_len = len; 00348 msg->ce_mask |= LOG_MSG_ATTR_PAYLOAD; 00349 return 0; 00350 } 00351 00352 const void *nfnl_log_msg_get_payload(const struct nfnl_log_msg *msg, int *len) 00353 { 00354 if (!(msg->ce_mask & LOG_MSG_ATTR_PAYLOAD)) { 00355 *len = 0; 00356 return NULL; 00357 } 00358 00359 *len = msg->log_msg_payload_len; 00360 return msg->log_msg_payload; 00361 } 00362 00363 int nfnl_log_msg_set_prefix(struct nfnl_log_msg *msg, void *prefix) 00364 { 00365 free(msg->log_msg_prefix); 00366 msg->log_msg_prefix = strdup(prefix); 00367 if (!msg->log_msg_prefix) 00368 return -NLE_NOMEM; 00369 00370 msg->ce_mask |= LOG_MSG_ATTR_PREFIX; 00371 return 0; 00372 } 00373 00374 const char *nfnl_log_msg_get_prefix(const struct nfnl_log_msg *msg) 00375 { 00376 return msg->log_msg_prefix; 00377 } 00378 00379 void nfnl_log_msg_set_uid(struct nfnl_log_msg *msg, uint32_t uid) 00380 { 00381 msg->log_msg_uid = uid; 00382 msg->ce_mask |= LOG_MSG_ATTR_UID; 00383 } 00384 00385 int nfnl_log_msg_test_uid(const struct nfnl_log_msg *msg) 00386 { 00387 return !!(msg->ce_mask & LOG_MSG_ATTR_UID); 00388 } 00389 00390 uint32_t nfnl_log_msg_get_uid(const struct nfnl_log_msg *msg) 00391 { 00392 return msg->log_msg_uid; 00393 } 00394 00395 void nfnl_log_msg_set_gid(struct nfnl_log_msg *msg, uint32_t gid) 00396 { 00397 msg->log_msg_gid = gid; 00398 msg->ce_mask |= LOG_MSG_ATTR_GID; 00399 } 00400 00401 int nfnl_log_msg_test_gid(const struct nfnl_log_msg *msg) 00402 { 00403 return !!(msg->ce_mask & LOG_MSG_ATTR_GID); 00404 } 00405 00406 uint32_t nfnl_log_msg_get_gid(const struct nfnl_log_msg *msg) 00407 { 00408 return msg->log_msg_gid; 00409 } 00410 00411 00412 void nfnl_log_msg_set_seq(struct nfnl_log_msg *msg, uint32_t seq) 00413 { 00414 msg->log_msg_seq = seq; 00415 msg->ce_mask |= LOG_MSG_ATTR_SEQ; 00416 } 00417 00418 int nfnl_log_msg_test_seq(const struct nfnl_log_msg *msg) 00419 { 00420 return !!(msg->ce_mask & LOG_MSG_ATTR_SEQ); 00421 } 00422 00423 uint32_t nfnl_log_msg_get_seq(const struct nfnl_log_msg *msg) 00424 { 00425 return msg->log_msg_seq; 00426 } 00427 00428 void nfnl_log_msg_set_seq_global(struct nfnl_log_msg *msg, uint32_t seq_global) 00429 { 00430 msg->log_msg_seq_global = seq_global; 00431 msg->ce_mask |= LOG_MSG_ATTR_SEQ_GLOBAL; 00432 } 00433 00434 int nfnl_log_msg_test_seq_global(const struct nfnl_log_msg *msg) 00435 { 00436 return !!(msg->ce_mask & LOG_MSG_ATTR_SEQ_GLOBAL); 00437 } 00438 00439 uint32_t nfnl_log_msg_get_seq_global(const struct nfnl_log_msg *msg) 00440 { 00441 return msg->log_msg_seq_global; 00442 } 00443 00444 /** @} */ 00445 00446 struct nl_object_ops log_msg_obj_ops = { 00447 .oo_name = "netfilter/log_msg", 00448 .oo_size = sizeof(struct nfnl_log_msg), 00449 .oo_free_data = log_msg_free_data, 00450 .oo_clone = log_msg_clone, 00451 .oo_dump = { 00452 [NL_DUMP_LINE] = log_msg_dump, 00453 [NL_DUMP_DETAILS] = log_msg_dump, 00454 [NL_DUMP_STATS] = log_msg_dump, 00455 }, 00456 }; 00457 00458 /** @} */