libnetfilter_log  1.0.2
libnetfilter_log.c
1 /* libnetfilter_log.c: generic library for access to NFLOG
2  *
3  * (C) 2005 by Harald Welte <laforge@gnumonks.org>
4  * (C) 2005, 2008-2010 by Pablo Neira Ayuso <pablo@netfilter.org>
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License version 2
8  * as published by the Free Software Foundation (or any later at your option)
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18  */
19 
20 #include <stdio.h>
21 #include <stdlib.h>
22 #include <unistd.h>
23 #include <string.h>
24 #include <ctype.h>
25 #include <time.h>
26 #include <errno.h>
27 #include <netinet/in.h>
28 #include <sys/socket.h>
29 #include "internal.h"
30 
31 #include <libnetfilter_log/linux_nfnetlink_log.h>
32 
33 #include <libnfnetlink/libnfnetlink.h>
34 #include <libnetfilter_log/libnetfilter_log.h>
35 
36 #include <libmnl/libmnl.h>
37 #include <linux/netfilter/nfnetlink_conntrack.h>
38 
68 struct nflog_handle
69 {
70  struct nfnl_handle *nfnlh;
71  struct nfnl_subsys_handle *nfnlssh;
72  struct nflog_g_handle *gh_list;
73 };
74 
75 struct nflog_g_handle
76 {
77  struct nflog_g_handle *next;
78  struct nflog_handle *h;
79  uint16_t id;
80 
81  nflog_callback *cb;
82  void *data;
83 };
84 
85 int nflog_errno;
86 
87 /***********************************************************************
88  * low level stuff
89  ***********************************************************************/
90 
91 static void del_gh(struct nflog_g_handle *gh)
92 {
93  struct nflog_g_handle *cur_gh, *prev_gh = NULL;
94 
95  for (cur_gh = gh->h->gh_list; cur_gh; cur_gh = cur_gh->next) {
96  if (cur_gh == gh) {
97  if (prev_gh)
98  prev_gh->next = gh->next;
99  else
100  gh->h->gh_list = gh->next;
101  return;
102  }
103  prev_gh = cur_gh;
104  }
105 }
106 
107 static void add_gh(struct nflog_g_handle *gh)
108 {
109  gh->next = gh->h->gh_list;
110  gh->h->gh_list = gh;
111 }
112 
113 static struct nflog_g_handle *find_gh(struct nflog_handle *h, uint16_t group)
114 {
115  struct nflog_g_handle *gh;
116 
117  for (gh = h->gh_list; gh; gh = gh->next) {
118  if (gh->id == group)
119  return gh;
120  }
121  return NULL;
122 }
123 
124 /* build a NFULNL_MSG_CONFIG message */
125 static int
126 __build_send_cfg_msg(struct nflog_handle *h, uint8_t command,
127  uint16_t groupnum, uint8_t pf)
128 {
129  union {
130  char buf[NFNL_HEADER_LEN
131  +NFA_LENGTH(sizeof(struct nfulnl_msg_config_cmd))];
132  struct nlmsghdr nmh;
133  } u;
134  struct nfulnl_msg_config_cmd cmd;
135 
136  nfnl_fill_hdr(h->nfnlssh, &u.nmh, 0, pf, groupnum,
137  NFULNL_MSG_CONFIG, NLM_F_REQUEST|NLM_F_ACK);
138 
139  cmd.command = command;
140  nfnl_addattr_l(&u.nmh, sizeof(u), NFULA_CFG_CMD, &cmd, sizeof(cmd));
141 
142  return nfnl_query(h->nfnlh, &u.nmh);
143 }
144 
145 static int __nflog_rcv_pkt(struct nlmsghdr *nlh, struct nfattr *nfa[],
146  void *data)
147 {
148  struct nfgenmsg *nfmsg = NLMSG_DATA(nlh);
149  struct nflog_handle *h = data;
150  uint16_t group = ntohs(nfmsg->res_id);
151  struct nflog_g_handle *gh = find_gh(h, group);
152  struct nflog_data nfldata;
153 
154  if (!gh)
155  return -ENODEV;
156 
157  if (!gh->cb)
158  return -ENODEV;
159 
160  nfldata.nfa = nfa;
161  return gh->cb(gh, nfmsg, &nfldata, gh->data);
162 }
163 
164 static struct nfnl_callback pkt_cb = {
165  .call = &__nflog_rcv_pkt,
166  .attr_count = NFULA_MAX,
167 };
168 
169 /* public interface */
170 
171 struct nfnl_handle *nflog_nfnlh(struct nflog_handle *h)
172 {
173  return h->nfnlh;
174 }
175 
245 int nflog_fd(struct nflog_handle *h)
246 {
247  return nfnl_fd(nflog_nfnlh(h));
248 }
249 
254 struct nflog_handle *nflog_open_nfnl(struct nfnl_handle *nfnlh)
255 {
256  struct nflog_handle *h;
257  int err;
258 
259  h = calloc(1, sizeof(*h));
260  if (!h)
261  return NULL;
262 
263  h->nfnlh = nfnlh;
264 
265  h->nfnlssh = nfnl_subsys_open(h->nfnlh, NFNL_SUBSYS_ULOG,
266  NFULNL_MSG_MAX, 0);
267  if (!h->nfnlssh) {
268  /* FIXME: nflog_errno */
269  goto out_free;
270  }
271 
272  pkt_cb.data = h;
273  err = nfnl_callback_register(h->nfnlssh, NFULNL_MSG_PACKET, &pkt_cb);
274  if (err < 0) {
275  nflog_errno = err;
276  goto out_close;
277  }
278 
279  return h;
280 out_close:
281  nfnl_close(h->nfnlh);
282 out_free:
283  free(h);
284  return NULL;
285 }
286 
304 struct nflog_handle *nflog_open(void)
305 {
306  struct nfnl_handle *nfnlh;
307  struct nflog_handle *lh;
308 
309  nfnlh = nfnl_open();
310  if (!nfnlh) {
311  /* FIXME: nflog_errno */
312  return NULL;
313  }
314 
315  /* disable netlink sequence tracking by default */
316  nfnl_unset_sequence_tracking(nfnlh);
317 
318  lh = nflog_open_nfnl(nfnlh);
319  if (!lh)
320  nfnl_close(nfnlh);
321 
322  return lh;
323 }
324 
343 int nflog_callback_register(struct nflog_g_handle *gh, nflog_callback *cb,
344  void *data)
345 {
346  gh->data = data;
347  gh->cb = cb;
348 
349  return 0;
350 }
351 
366 int nflog_handle_packet(struct nflog_handle *h, char *buf, int len)
367 {
368  return nfnl_handle_packet(h->nfnlh, buf, len);
369 }
370 
401 int nflog_close(struct nflog_handle *h)
402 {
403  int ret = nfnl_close(h->nfnlh);
404  free(h);
405  return ret;
406 }
407 
420 int nflog_bind_pf(struct nflog_handle *h, uint16_t pf)
421 {
422  return __build_send_cfg_msg(h, NFULNL_CFG_CMD_PF_BIND, 0, pf);
423 }
424 
425 
437 int nflog_unbind_pf(struct nflog_handle *h, uint16_t pf)
438 {
439  return __build_send_cfg_msg(h, NFULNL_CFG_CMD_PF_UNBIND, 0, pf);
440 }
441 
463 struct nflog_g_handle *
464 nflog_bind_group(struct nflog_handle *h, uint16_t num)
465 {
466  struct nflog_g_handle *gh;
467 
468  if (find_gh(h, num)) {
469  errno = EBUSY;
470  return NULL;
471  }
472 
473  gh = calloc(1, sizeof(*gh));
474  if (!gh)
475  return NULL;
476 
477  gh->h = h;
478  gh->id = num;
479 
480  if (__build_send_cfg_msg(h, NFULNL_CFG_CMD_BIND, num, 0) < 0) {
481  free(gh);
482  return NULL;
483  }
484 
485  add_gh(gh);
486  return gh;
487 }
488 
506 int nflog_unbind_group(struct nflog_g_handle *gh)
507 {
508  int ret = __build_send_cfg_msg(gh->h, NFULNL_CFG_CMD_UNBIND, gh->id, 0);
509  if (ret == 0) {
510  del_gh(gh);
511  free(gh);
512  }
513 
514  return ret;
515 }
516 
534 int nflog_set_mode(struct nflog_g_handle *gh,
535  uint8_t mode, uint32_t range)
536 {
537  union {
538  char buf[NFNL_HEADER_LEN
539  +NFA_LENGTH(sizeof(struct nfulnl_msg_config_mode))];
540  struct nlmsghdr nmh;
541  } u;
542  struct nfulnl_msg_config_mode params;
543 
544  nfnl_fill_hdr(gh->h->nfnlssh, &u.nmh, 0, AF_UNSPEC, gh->id,
545  NFULNL_MSG_CONFIG, NLM_F_REQUEST|NLM_F_ACK);
546 
547  params.copy_range = htonl(range); /* copy_range is short */
548  params.copy_mode = mode;
549  nfnl_addattr_l(&u.nmh, sizeof(u), NFULA_CFG_MODE, &params,
550  sizeof(params));
551 
552  return nfnl_query(gh->h->nfnlh, &u.nmh);
553 }
554 
569 int nflog_set_timeout(struct nflog_g_handle *gh, uint32_t timeout)
570 {
571  union {
572  char buf[NFNL_HEADER_LEN+NFA_LENGTH(sizeof(uint32_t))];
573  struct nlmsghdr nmh;
574  } u;
575 
576  nfnl_fill_hdr(gh->h->nfnlssh, &u.nmh, 0, AF_UNSPEC, gh->id,
577  NFULNL_MSG_CONFIG, NLM_F_REQUEST|NLM_F_ACK);
578 
579  nfnl_addattr32(&u.nmh, sizeof(u), NFULA_CFG_TIMEOUT, htonl(timeout));
580 
581  return nfnl_query(gh->h->nfnlh, &u.nmh);
582 }
583 
596 int nflog_set_qthresh(struct nflog_g_handle *gh, uint32_t qthresh)
597 {
598  union {
599  char buf[NFNL_HEADER_LEN+NFA_LENGTH(sizeof(uint32_t))];
600  struct nlmsghdr nmh;
601  } u;
602 
603  nfnl_fill_hdr(gh->h->nfnlssh, &u.nmh, 0, AF_UNSPEC, gh->id,
604  NFULNL_MSG_CONFIG, NLM_F_REQUEST|NLM_F_ACK);
605 
606  nfnl_addattr32(&u.nmh, sizeof(u), NFULA_CFG_QTHRESH, htonl(qthresh));
607 
608  return nfnl_query(gh->h->nfnlh, &u.nmh);
609 }
610 
627 int nflog_set_nlbufsiz(struct nflog_g_handle *gh, uint32_t nlbufsiz)
628 {
629  union {
630  char buf[NFNL_HEADER_LEN+NFA_LENGTH(sizeof(uint32_t))];
631  struct nlmsghdr nmh;
632  } u;
633  int status;
634 
635  nfnl_fill_hdr(gh->h->nfnlssh, &u.nmh, 0, AF_UNSPEC, gh->id,
636  NFULNL_MSG_CONFIG, NLM_F_REQUEST|NLM_F_ACK);
637 
638  nfnl_addattr32(&u.nmh, sizeof(u), NFULA_CFG_NLBUFSIZ, htonl(nlbufsiz));
639 
640  status = nfnl_query(gh->h->nfnlh, &u.nmh);
641 
642  /* we try to have space for at least 10 messages in the socket buffer */
643  if (status >= 0)
644  nfnl_rcvbufsiz(gh->h->nfnlh, 10*nlbufsiz);
645 
646  return status;
647 }
648 
664 int nflog_set_flags(struct nflog_g_handle *gh, uint16_t flags)
665 {
666  union {
667  char buf[NFNL_HEADER_LEN+NFA_LENGTH(sizeof(uint16_t))];
668  struct nlmsghdr nmh;
669  } u;
670 
671  nfnl_fill_hdr(gh->h->nfnlssh, &u.nmh, 0, AF_UNSPEC, gh->id,
672  NFULNL_MSG_CONFIG, NLM_F_REQUEST|NLM_F_ACK);
673 
674  nfnl_addattr16(&u.nmh, sizeof(u), NFULA_CFG_FLAGS, htons(flags));
675 
676  return nfnl_query(gh->h->nfnlh, &u.nmh);
677 }
678 
712 struct nfulnl_msg_packet_hdr *nflog_get_msg_packet_hdr(struct nflog_data *nfad)
713 {
714  return nfnl_get_pointer_to_data(nfad->nfa, NFULA_PACKET_HDR,
715  struct nfulnl_msg_packet_hdr);
716 }
717 
724 uint16_t nflog_get_hwtype(struct nflog_data *nfad)
725 {
726  return ntohs(nfnl_get_data(nfad->nfa, NFULA_HWTYPE, uint16_t));
727 }
728 
735 uint16_t nflog_get_msg_packet_hwhdrlen(struct nflog_data *nfad)
736 {
737  return ntohs(nfnl_get_data(nfad->nfa, NFULA_HWLEN, uint16_t));
738 }
739 
746 char *nflog_get_msg_packet_hwhdr(struct nflog_data *nfad)
747 {
748  return nfnl_get_pointer_to_data(nfad->nfa, NFULA_HWHEADER, char);
749 }
750 
757 uint32_t nflog_get_nfmark(struct nflog_data *nfad)
758 {
759  return ntohl(nfnl_get_data(nfad->nfa, NFULA_MARK, uint32_t));
760 }
761 
773 int nflog_get_timestamp(struct nflog_data *nfad, struct timeval *tv)
774 {
775  struct nfulnl_msg_packet_timestamp *uts;
776 
777  uts = nfnl_get_pointer_to_data(nfad->nfa, NFULA_TIMESTAMP,
778  struct nfulnl_msg_packet_timestamp);
779  if (!uts)
780  return -1;
781 
782  tv->tv_sec = __be64_to_cpu(uts->sec);
783  tv->tv_usec = __be64_to_cpu(uts->usec);
784 
785  return 0;
786 }
787 
799 uint32_t nflog_get_indev(struct nflog_data *nfad)
800 {
801  return ntohl(nfnl_get_data(nfad->nfa, NFULA_IFINDEX_INDEV, uint32_t));
802 }
803 
813 uint32_t nflog_get_physindev(struct nflog_data *nfad)
814 {
815  return ntohl(nfnl_get_data(nfad->nfa, NFULA_IFINDEX_PHYSINDEV, uint32_t));
816 }
817 
826 uint32_t nflog_get_outdev(struct nflog_data *nfad)
827 {
828  return ntohl(nfnl_get_data(nfad->nfa, NFULA_IFINDEX_OUTDEV, uint32_t));
829 }
830 
839 uint32_t nflog_get_physoutdev(struct nflog_data *nfad)
840 {
841  return ntohl(nfnl_get_data(nfad->nfa, NFULA_IFINDEX_PHYSOUTDEV, uint32_t));
842 }
843 
867 struct nfulnl_msg_packet_hw *nflog_get_packet_hw(struct nflog_data *nfad)
868 {
869  return nfnl_get_pointer_to_data(nfad->nfa, NFULA_HWADDR,
870  struct nfulnl_msg_packet_hw);
871 }
872 
884 int nflog_get_payload(struct nflog_data *nfad, char **data)
885 {
886  *data = nfnl_get_pointer_to_data(nfad->nfa, NFULA_PAYLOAD, char);
887  if (*data)
888  return NFA_PAYLOAD(nfad->nfa[NFULA_PAYLOAD-1]);
889 
890  return -1;
891 }
892 
900 char *nflog_get_prefix(struct nflog_data *nfad)
901 {
902  return nfnl_get_pointer_to_data(nfad->nfa, NFULA_PREFIX, char);
903 }
904 
914 int nflog_get_uid(struct nflog_data *nfad, uint32_t *uid)
915 {
916  if (!nfnl_attr_present(nfad->nfa, NFULA_UID))
917  return -1;
918 
919  *uid = ntohl(nfnl_get_data(nfad->nfa, NFULA_UID, uint32_t));
920  return 0;
921 }
922 
932 int nflog_get_gid(struct nflog_data *nfad, uint32_t *gid)
933 {
934  if (!nfnl_attr_present(nfad->nfa, NFULA_GID))
935  return -1;
936 
937  *gid = ntohl(nfnl_get_data(nfad->nfa, NFULA_GID, uint32_t));
938  return 0;
939 }
940 
952 int nflog_get_seq(struct nflog_data *nfad, uint32_t *seq)
953 {
954  if (!nfnl_attr_present(nfad->nfa, NFULA_SEQ))
955  return -1;
956 
957  *seq = ntohl(nfnl_get_data(nfad->nfa, NFULA_SEQ, uint32_t));
958  return 0;
959 }
960 
972 int nflog_get_seq_global(struct nflog_data *nfad, uint32_t *seq)
973 {
974  if (!nfnl_attr_present(nfad->nfa, NFULA_SEQ_GLOBAL))
975  return -1;
976 
977  *seq = ntohl(nfnl_get_data(nfad->nfa, NFULA_SEQ_GLOBAL, uint32_t));
978  return 0;
979 }
980 
990 int nflog_get_ctid(struct nflog_data *nfad, uint32_t *id)
991 {
992  struct nlattr *cta = (struct nlattr *)nfad->nfa[NFULA_CT - 1];
993  struct nlattr *attr, *ida = NULL;
994 
995  if (!cta)
996  return -1;
997 
998  mnl_attr_for_each_nested(attr, cta) {
999  if (mnl_attr_get_type(attr) == CTA_ID) {
1000  ida = attr;
1001  break;
1002  }
1003  }
1004 
1005  if (!ida || mnl_attr_validate(ida, MNL_TYPE_U32) < 0)
1006  return -1;
1007 
1008  *id = ntohl(mnl_attr_get_u32(ida));
1009 
1010  return 0;
1011 }
1012 
1017 #define SNPRINTF_FAILURE(ret, rem, offset, len) \
1018 do { \
1019  if (ret < 0) \
1020  return ret; \
1021  len += ret; \
1022  if (ret > rem) \
1023  ret = rem; \
1024  offset += ret; \
1025  rem -= ret; \
1026 } while (0)
1027 
1066 int nflog_snprintf_xml(char *buf, size_t rem, struct nflog_data *tb, int flags)
1067 {
1068  int size, offset = 0, len = 0, ret;
1069  struct nfulnl_msg_packet_hw *hwph;
1070  struct nfulnl_msg_packet_hdr *ph;
1071  uint32_t mark, ifi, ctid;
1072  char *data;
1073 
1074  size = snprintf(buf + offset, rem, "<log>");
1075  SNPRINTF_FAILURE(size, rem, offset, len);
1076 
1077  if (flags & NFLOG_XML_TIME) {
1078  time_t t;
1079  struct tm tm;
1080 
1081  t = time(NULL);
1082  if (localtime_r(&t, &tm) == NULL)
1083  return -1;
1084 
1085  size = snprintf(buf + offset, rem, "<when>");
1086  SNPRINTF_FAILURE(size, rem, offset, len);
1087 
1088  size = snprintf(buf + offset, rem,
1089  "<hour>%d</hour>", tm.tm_hour);
1090  SNPRINTF_FAILURE(size, rem, offset, len);
1091 
1092  size = snprintf(buf + offset,
1093  rem, "<min>%02d</min>", tm.tm_min);
1094  SNPRINTF_FAILURE(size, rem, offset, len);
1095 
1096  size = snprintf(buf + offset,
1097  rem, "<sec>%02d</sec>", tm.tm_sec);
1098  SNPRINTF_FAILURE(size, rem, offset, len);
1099 
1100  size = snprintf(buf + offset, rem, "<wday>%d</wday>",
1101  tm.tm_wday + 1);
1102  SNPRINTF_FAILURE(size, rem, offset, len);
1103 
1104  size = snprintf(buf + offset, rem, "<day>%d</day>", tm.tm_mday);
1105  SNPRINTF_FAILURE(size, rem, offset, len);
1106 
1107  size = snprintf(buf + offset, rem, "<month>%d</month>",
1108  tm.tm_mon + 1);
1109  SNPRINTF_FAILURE(size, rem, offset, len);
1110 
1111  size = snprintf(buf + offset, rem, "<year>%d</year>",
1112  1900 + tm.tm_year);
1113  SNPRINTF_FAILURE(size, rem, offset, len);
1114 
1115  size = snprintf(buf + offset, rem, "</when>");
1116  SNPRINTF_FAILURE(size, rem, offset, len);
1117  }
1118 
1119  data = nflog_get_prefix(tb);
1120  if (data && (flags & NFLOG_XML_PREFIX)) {
1121  size = snprintf(buf + offset, rem, "<prefix>%s</prefix>", data);
1122  SNPRINTF_FAILURE(size, rem, offset, len);
1123  }
1124 
1125  ph = nflog_get_msg_packet_hdr(tb);
1126  if (ph) {
1127  size = snprintf(buf + offset, rem, "<hook>%u</hook>", ph->hook);
1128  SNPRINTF_FAILURE(size, rem, offset, len);
1129 
1130  hwph = nflog_get_packet_hw(tb);
1131  if (hwph && (flags & NFLOG_XML_HW)) {
1132  int i, hlen = ntohs(hwph->hw_addrlen);
1133 
1134  size = snprintf(buf + offset, rem, "<hw><proto>%04x"
1135  "</proto>",
1136  ntohs(ph->hw_protocol));
1137  SNPRINTF_FAILURE(size, rem, offset, len);
1138 
1139  size = snprintf(buf + offset, rem, "<src>");
1140  SNPRINTF_FAILURE(size, rem, offset, len);
1141 
1142  for (i=0; i<hlen; i++) {
1143  size = snprintf(buf + offset, rem, "%02x",
1144  hwph->hw_addr[i]);
1145  SNPRINTF_FAILURE(size, rem, offset, len);
1146  }
1147 
1148  size = snprintf(buf + offset, rem, "</src></hw>");
1149  SNPRINTF_FAILURE(size, rem, offset, len);
1150  } else if (flags & NFLOG_XML_HW) {
1151  size = snprintf(buf + offset, rem, "<hw><proto>%04x"
1152  "</proto></hw>",
1153  ntohs(ph->hw_protocol));
1154  SNPRINTF_FAILURE(size, rem, offset, len);
1155  }
1156  }
1157 
1158  mark = nflog_get_nfmark(tb);
1159  if (mark && (flags & NFLOG_XML_MARK)) {
1160  size = snprintf(buf + offset, rem, "<mark>%u</mark>", mark);
1161  SNPRINTF_FAILURE(size, rem, offset, len);
1162  }
1163 
1164  ifi = nflog_get_indev(tb);
1165  if (ifi && (flags & NFLOG_XML_DEV)) {
1166  size = snprintf(buf + offset, rem, "<indev>%u</indev>", ifi);
1167  SNPRINTF_FAILURE(size, rem, offset, len);
1168  }
1169 
1170  ifi = nflog_get_outdev(tb);
1171  if (ifi && (flags & NFLOG_XML_DEV)) {
1172  size = snprintf(buf + offset, rem, "<outdev>%u</outdev>", ifi);
1173  SNPRINTF_FAILURE(size, rem, offset, len);
1174  }
1175 
1176  ifi = nflog_get_physindev(tb);
1177  if (ifi && (flags & NFLOG_XML_PHYSDEV)) {
1178  size = snprintf(buf + offset, rem,
1179  "<physindev>%u</physindev>", ifi);
1180  SNPRINTF_FAILURE(size, rem, offset, len);
1181  }
1182 
1183  ifi = nflog_get_physoutdev(tb);
1184  if (ifi && (flags & NFLOG_XML_PHYSDEV)) {
1185  size = snprintf(buf + offset, rem,
1186  "<physoutdev>%u</physoutdev>", ifi);
1187  SNPRINTF_FAILURE(size, rem, offset, len);
1188  }
1189 
1190  if (flags & NFLOG_XML_CTID) {
1191  ret = nflog_get_ctid(tb, &ctid);
1192  if (ret >= 0) {
1193  size = snprintf(buf + offset, rem,
1194  "<ctid>%u</ctid>", ctid);
1195  SNPRINTF_FAILURE(size, rem, offset, len);
1196  }
1197  }
1198 
1199  ret = nflog_get_payload(tb, &data);
1200  if (ret >= 0 && (flags & NFLOG_XML_PAYLOAD)) {
1201  int i;
1202 
1203  size = snprintf(buf + offset, rem, "<payload>");
1204  SNPRINTF_FAILURE(size, rem, offset, len);
1205 
1206  for (i=0; i<ret; i++) {
1207  size = snprintf(buf + offset, rem, "%02x",
1208  data[i] & 0xff);
1209  SNPRINTF_FAILURE(size, rem, offset, len);
1210  }
1211 
1212  size = snprintf(buf + offset, rem, "</payload>");
1213  SNPRINTF_FAILURE(size, rem, offset, len);
1214  }
1215 
1216  size = snprintf(buf + offset, rem, "</log>");
1217  SNPRINTF_FAILURE(size, rem, offset, len);
1218 
1219  return len;
1220 }
1221 
struct nflog_handle * nflog_open(void)
int nflog_bind_pf(struct nflog_handle *h, uint16_t pf)
int nflog_unbind_pf(struct nflog_handle *h, uint16_t pf)
int nflog_close(struct nflog_handle *h)
int nflog_set_qthresh(struct nflog_g_handle *gh, uint32_t qthresh)
int nflog_set_mode(struct nflog_g_handle *gh, uint8_t mode, uint32_t range)
struct nflog_g_handle * nflog_bind_group(struct nflog_handle *h, uint16_t num)
int nflog_set_nlbufsiz(struct nflog_g_handle *gh, uint32_t nlbufsiz)
int nflog_handle_packet(struct nflog_handle *h, char *buf, int len)
int nflog_set_flags(struct nflog_g_handle *gh, uint16_t flags)
int nflog_set_timeout(struct nflog_g_handle *gh, uint32_t timeout)
int nflog_callback_register(struct nflog_g_handle *gh, nflog_callback *cb, void *data)
int nflog_fd(struct nflog_handle *h)
int nflog_unbind_group(struct nflog_g_handle *gh)
int nflog_get_seq(struct nflog_data *nfad, uint32_t *seq)
int nflog_get_gid(struct nflog_data *nfad, uint32_t *gid)
uint32_t nflog_get_outdev(struct nflog_data *nfad)
int nflog_get_seq_global(struct nflog_data *nfad, uint32_t *seq)
uint32_t nflog_get_nfmark(struct nflog_data *nfad)
struct nfulnl_msg_packet_hw * nflog_get_packet_hw(struct nflog_data *nfad)
int nflog_get_uid(struct nflog_data *nfad, uint32_t *uid)
uint16_t nflog_get_msg_packet_hwhdrlen(struct nflog_data *nfad)
uint16_t nflog_get_hwtype(struct nflog_data *nfad)
uint32_t nflog_get_indev(struct nflog_data *nfad)
char * nflog_get_prefix(struct nflog_data *nfad)
struct nfulnl_msg_packet_hdr * nflog_get_msg_packet_hdr(struct nflog_data *nfad)
int nflog_get_ctid(struct nflog_data *nfad, uint32_t *id)
int nflog_get_payload(struct nflog_data *nfad, char **data)
uint32_t nflog_get_physoutdev(struct nflog_data *nfad)
uint32_t nflog_get_physindev(struct nflog_data *nfad)
int nflog_get_timestamp(struct nflog_data *nfad, struct timeval *tv)
char * nflog_get_msg_packet_hwhdr(struct nflog_data *nfad)
int nflog_snprintf_xml(char *buf, size_t rem, struct nflog_data *tb, int flags)