00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014 #include <netlink-local.h>
00015 #include <netlink/netfilter/nfnl.h>
00016 #include <netlink/netfilter/log.h>
00017
00018
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
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
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
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
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