libnl 1.1

lib/netfilter/log_obj.c

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