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/netfilter.h>
00017 #include <netlink/netfilter/log_msg.h>
00018
00019
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
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
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
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
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