libnl 1.1
|
00001 /* 00002 * lib/netfilter/log_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-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 #include <netlink-local.h> 00015 #include <netlink/netfilter/nfnl.h> 00016 #include <netlink/netfilter/log.h> 00017 00018 /** @cond SKIP */ 00019 #define LOG_ATTR_FAMILY (1UL << 0) 00020 #define LOG_ATTR_HWPROTO (1UL << 1) 00021 #define LOG_ATTR_HOOK (1UL << 2) 00022 #define LOG_ATTR_MARK (1UL << 3) 00023 #define LOG_ATTR_TIMESTAMP (1UL << 4) 00024 #define LOG_ATTR_INDEV (1UL << 5) 00025 #define LOG_ATTR_OUTDEV (1UL << 6) 00026 #define LOG_ATTR_PHYSINDEV (1UL << 7) 00027 #define LOG_ATTR_PHYSOUTDEV (1UL << 8) 00028 #define LOG_ATTR_HWADDR (1UL << 9) 00029 #define LOG_ATTR_PAYLOAD (1UL << 10) 00030 #define LOG_ATTR_PREFIX (1UL << 11) 00031 #define LOG_ATTR_UID (1UL << 12) 00032 #define LOG_ATTR_SEQ (1UL << 13) 00033 #define LOG_ATTR_SEQ_GLOBAL (1UL << 14) 00034 /** @endcond */ 00035 00036 static void log_free_data(struct nl_object *c) 00037 { 00038 struct nfnl_log *log = (struct nfnl_log *) c; 00039 00040 if (log == NULL) 00041 return; 00042 00043 free(log->log_payload); 00044 free(log->log_prefix); 00045 } 00046 00047 static int log_clone(struct nl_object *_dst, struct nl_object *_src) 00048 { 00049 struct nfnl_log *dst = (struct nfnl_log *) _dst; 00050 struct nfnl_log *src = (struct nfnl_log *) _src; 00051 int err; 00052 00053 if (src->log_payload) { 00054 err = nfnl_log_set_payload(dst, src->log_payload, 00055 src->log_payload_len); 00056 if (err < 0) 00057 goto errout; 00058 } 00059 00060 if (src->log_prefix) { 00061 err = nfnl_log_set_prefix(dst, src->log_prefix); 00062 if (err < 0) 00063 goto errout; 00064 } 00065 00066 return 0; 00067 errout: 00068 return err; 00069 } 00070 00071 static int log_dump(struct nl_object *a, struct nl_dump_params *p) 00072 { 00073 struct nfnl_log *log = (struct nfnl_log *) a; 00074 struct nl_cache *link_cache; 00075 char buf[64]; 00076 00077 link_cache = nl_cache_mngt_require("route/link"); 00078 00079 if (log->ce_mask & LOG_ATTR_PREFIX) 00080 dp_dump(p, "%s", log->log_prefix); 00081 00082 if (log->ce_mask & LOG_ATTR_INDEV) { 00083 if (link_cache) 00084 dp_dump(p, "IN=%s ", 00085 rtnl_link_i2name(link_cache, log->log_indev, 00086 buf, sizeof(buf))); 00087 else 00088 dp_dump(p, "IN=%d ", log->log_indev); 00089 } 00090 00091 if (log->ce_mask & LOG_ATTR_PHYSINDEV) { 00092 if (link_cache) 00093 dp_dump(p, "PHYSIN=%s ", 00094 rtnl_link_i2name(link_cache, log->log_physindev, 00095 buf, sizeof(buf))); 00096 else 00097 dp_dump(p, "IN=%d ", log->log_physindev); 00098 } 00099 00100 if (log->ce_mask & LOG_ATTR_OUTDEV) { 00101 if (link_cache) 00102 dp_dump(p, "OUT=%s ", 00103 rtnl_link_i2name(link_cache, log->log_outdev, 00104 buf, sizeof(buf))); 00105 else 00106 dp_dump(p, "OUT=%d ", log->log_outdev); 00107 } 00108 00109 if (log->ce_mask & LOG_ATTR_PHYSOUTDEV) { 00110 if (link_cache) 00111 dp_dump(p, "PHYSOUT=%s ", 00112 rtnl_link_i2name(link_cache,log->log_physoutdev, 00113 buf, sizeof(buf))); 00114 else 00115 dp_dump(p, "PHYSOUT=%d ", log->log_physoutdev); 00116 } 00117 00118 if (log->ce_mask & LOG_ATTR_HWADDR) { 00119 int i; 00120 00121 dp_dump(p, "MAC"); 00122 for (i = 0; i < log->log_hwaddr_len; i++) 00123 dp_dump(p, "%c%02x", i?':':'=', log->log_hwaddr[i]); 00124 dp_dump(p, " "); 00125 } 00126 00127 /* FIXME: parse the payload to get iptables LOG compatible format */ 00128 00129 if (log->ce_mask & LOG_ATTR_FAMILY) 00130 dp_dump(p, "FAMILY=%s ", 00131 nl_af2str(log->log_family, buf, sizeof(buf))); 00132 00133 if (log->ce_mask & LOG_ATTR_HWPROTO) 00134 dp_dump(p, "HWPROTO=%s ", 00135 nl_ether_proto2str(ntohs(log->log_hwproto), 00136 buf, sizeof(buf))); 00137 00138 if (log->ce_mask & LOG_ATTR_HOOK) 00139 dp_dump(p, "HOOK=%d ", log->log_hook); 00140 00141 if (log->ce_mask & LOG_ATTR_MARK) 00142 dp_dump(p, "MARK=%d ", log->log_mark); 00143 00144 if (log->ce_mask & LOG_ATTR_PAYLOAD) 00145 dp_dump(p, "PAYLOADLEN=%d ", log->log_payload_len); 00146 00147 if (log->ce_mask & LOG_ATTR_SEQ) 00148 dp_dump(p, "SEQ=%d ", log->log_seq); 00149 00150 if (log->ce_mask & LOG_ATTR_SEQ_GLOBAL) 00151 dp_dump(p, "SEQGLOBAL=%d ", log->log_seq_global); 00152 00153 dp_dump(p, "\n"); 00154 00155 return 1; 00156 } 00157 00158 /** 00159 * @name Allocation/Freeing 00160 * @{ 00161 */ 00162 00163 struct nfnl_log *nfnl_log_alloc(void) 00164 { 00165 return (struct nfnl_log *) nl_object_alloc(&log_obj_ops); 00166 } 00167 00168 void nfnl_log_get(struct nfnl_log *log) 00169 { 00170 nl_object_get((struct nl_object *) log); 00171 } 00172 00173 void nfnl_log_put(struct nfnl_log *log) 00174 { 00175 nl_object_put((struct nl_object *) log); 00176 } 00177 00178 /** @} */ 00179 00180 /** 00181 * @name Attributes 00182 * @{ 00183 */ 00184 00185 void nfnl_log_set_family(struct nfnl_log *log, uint8_t family) 00186 { 00187 log->log_family = family; 00188 log->ce_mask |= LOG_ATTR_FAMILY; 00189 } 00190 00191 uint8_t nfnl_log_get_family(const struct nfnl_log *log) 00192 { 00193 if (log->ce_mask & LOG_ATTR_FAMILY) 00194 return log->log_family; 00195 else 00196 return AF_UNSPEC; 00197 } 00198 00199 void nfnl_log_set_hwproto(struct nfnl_log *log, uint16_t hwproto) 00200 { 00201 log->log_hwproto = hwproto; 00202 log->ce_mask |= LOG_ATTR_HWPROTO; 00203 } 00204 00205 int nfnl_log_test_hwproto(const struct nfnl_log *log) 00206 { 00207 return !!(log->ce_mask & LOG_ATTR_HWPROTO); 00208 } 00209 00210 uint16_t nfnl_log_get_hwproto(const struct nfnl_log *log) 00211 { 00212 return log->log_hwproto; 00213 } 00214 00215 void nfnl_log_set_hook(struct nfnl_log *log, uint8_t hook) 00216 { 00217 log->log_hook = hook; 00218 log->ce_mask |= LOG_ATTR_HOOK; 00219 } 00220 00221 int nfnl_log_test_hook(const struct nfnl_log *log) 00222 { 00223 return !!(log->ce_mask & LOG_ATTR_HOOK); 00224 } 00225 00226 uint8_t nfnl_log_get_hook(const struct nfnl_log *log) 00227 { 00228 return log->log_hook; 00229 } 00230 00231 void nfnl_log_set_mark(struct nfnl_log *log, uint32_t mark) 00232 { 00233 log->log_mark = mark; 00234 log->ce_mask |= LOG_ATTR_MARK; 00235 } 00236 00237 int nfnl_log_test_mark(const struct nfnl_log *log) 00238 { 00239 return !!(log->ce_mask & LOG_ATTR_MARK); 00240 } 00241 00242 uint32_t nfnl_log_get_mark(const struct nfnl_log *log) 00243 { 00244 return log->log_mark; 00245 } 00246 00247 void nfnl_log_set_timestamp(struct nfnl_log *log, struct timeval *tv) 00248 { 00249 log->log_timestamp.tv_sec = tv->tv_sec; 00250 log->log_timestamp.tv_usec = tv->tv_usec; 00251 log->ce_mask |= LOG_ATTR_TIMESTAMP; 00252 } 00253 00254 const struct timeval *nfnl_log_get_timestamp(const struct nfnl_log *log) 00255 { 00256 if (!(log->ce_mask & LOG_ATTR_TIMESTAMP)) 00257 return NULL; 00258 return &log->log_timestamp; 00259 } 00260 00261 void nfnl_log_set_indev(struct nfnl_log *log, uint32_t indev) 00262 { 00263 log->log_indev = indev; 00264 log->ce_mask |= LOG_ATTR_INDEV; 00265 } 00266 00267 uint32_t nfnl_log_get_indev(const struct nfnl_log *log) 00268 { 00269 return log->log_indev; 00270 } 00271 00272 void nfnl_log_set_outdev(struct nfnl_log *log, uint32_t outdev) 00273 { 00274 log->log_outdev = outdev; 00275 log->ce_mask |= LOG_ATTR_OUTDEV; 00276 } 00277 00278 uint32_t nfnl_log_get_outdev(const struct nfnl_log *log) 00279 { 00280 return log->log_outdev; 00281 } 00282 00283 void nfnl_log_set_physindev(struct nfnl_log *log, uint32_t physindev) 00284 { 00285 log->log_physindev = physindev; 00286 log->ce_mask |= LOG_ATTR_PHYSINDEV; 00287 } 00288 00289 uint32_t nfnl_log_get_physindev(const struct nfnl_log *log) 00290 { 00291 return log->log_physindev; 00292 } 00293 00294 void nfnl_log_set_physoutdev(struct nfnl_log *log, uint32_t physoutdev) 00295 { 00296 log->log_physoutdev = physoutdev; 00297 log->ce_mask |= LOG_ATTR_PHYSOUTDEV; 00298 } 00299 00300 uint32_t nfnl_log_get_physoutdev(const struct nfnl_log *log) 00301 { 00302 return log->log_physoutdev; 00303 } 00304 00305 void nfnl_log_set_hwaddr(struct nfnl_log *log, uint8_t *hwaddr, int len) 00306 { 00307 if (len > sizeof(log->log_hwaddr)) 00308 len = sizeof(log->log_hwaddr); 00309 log->log_hwaddr_len = len; 00310 memcpy(log->log_hwaddr, hwaddr, len); 00311 log->ce_mask |= LOG_ATTR_HWADDR; 00312 } 00313 00314 const uint8_t *nfnl_log_get_hwaddr(const struct nfnl_log *log, int *len) 00315 { 00316 if (!(log->ce_mask & LOG_ATTR_HWADDR)) { 00317 *len = 0; 00318 return NULL; 00319 } 00320 00321 *len = log->log_hwaddr_len; 00322 return log->log_hwaddr; 00323 } 00324 00325 int nfnl_log_set_payload(struct nfnl_log *log, uint8_t *payload, int len) 00326 { 00327 free(log->log_payload); 00328 log->log_payload = malloc(len); 00329 if (!log->log_payload) 00330 return nl_errno(ENOMEM); 00331 00332 memcpy(log->log_payload, payload, len); 00333 log->log_payload_len = len; 00334 log->ce_mask |= LOG_ATTR_PAYLOAD; 00335 return 0; 00336 } 00337 00338 const void *nfnl_log_get_payload(const struct nfnl_log *log, int *len) 00339 { 00340 if (!(log->ce_mask & LOG_ATTR_PAYLOAD)) { 00341 *len = 0; 00342 return NULL; 00343 } 00344 00345 *len = log->log_payload_len; 00346 return log->log_payload; 00347 } 00348 00349 int nfnl_log_set_prefix(struct nfnl_log *log, void *prefix) 00350 { 00351 free(log->log_prefix); 00352 log->log_prefix = strdup(prefix); 00353 if (!log->log_prefix) 00354 return nl_errno(ENOMEM); 00355 00356 log->ce_mask |= LOG_ATTR_PREFIX; 00357 return 0; 00358 } 00359 00360 const char *nfnl_log_get_prefix(const struct nfnl_log *log) 00361 { 00362 return log->log_prefix; 00363 } 00364 00365 void nfnl_log_set_uid(struct nfnl_log *log, uint32_t uid) 00366 { 00367 log->log_uid = uid; 00368 log->ce_mask |= LOG_ATTR_UID; 00369 } 00370 00371 int nfnl_log_test_uid(const struct nfnl_log *log) 00372 { 00373 return !!(log->ce_mask & LOG_ATTR_UID); 00374 } 00375 00376 uint32_t nfnl_log_get_uid(const struct nfnl_log *log) 00377 { 00378 return log->log_uid; 00379 } 00380 00381 void nfnl_log_set_seq(struct nfnl_log *log, uint32_t seq) 00382 { 00383 log->log_seq = seq; 00384 log->ce_mask |= LOG_ATTR_SEQ; 00385 } 00386 00387 int nfnl_log_test_seq(const struct nfnl_log *log) 00388 { 00389 return !!(log->ce_mask & LOG_ATTR_SEQ); 00390 } 00391 00392 uint32_t nfnl_log_get_seq(const struct nfnl_log *log) 00393 { 00394 return log->log_seq; 00395 } 00396 00397 void nfnl_log_set_seq_global(struct nfnl_log *log, uint32_t seq_global) 00398 { 00399 log->log_seq_global = seq_global; 00400 log->ce_mask |= LOG_ATTR_SEQ_GLOBAL; 00401 } 00402 00403 int nfnl_log_test_seq_global(const struct nfnl_log *log) 00404 { 00405 return !!(log->ce_mask & LOG_ATTR_SEQ_GLOBAL); 00406 } 00407 00408 uint32_t nfnl_log_get_seq_global(const struct nfnl_log *log) 00409 { 00410 return log->log_seq_global; 00411 } 00412 00413 /** @} */ 00414 00415 struct nl_object_ops log_obj_ops = { 00416 .oo_name = "netfilter/log", 00417 .oo_size = sizeof(struct nfnl_log), 00418 .oo_free_data = log_free_data, 00419 .oo_clone = log_clone, 00420 .oo_dump[NL_DUMP_BRIEF] = log_dump, 00421 .oo_dump[NL_DUMP_FULL] = log_dump, 00422 .oo_dump[NL_DUMP_STATS] = log_dump, 00423 }; 00424 00425 /** @} */