27 #include <netinet/in.h>
28 #include <sys/socket.h>
31 #include <libnetfilter_log/linux_nfnetlink_log.h>
33 #include <libnfnetlink/libnfnetlink.h>
34 #include <libnetfilter_log/libnetfilter_log.h>
67 struct nfnl_handle *nfnlh;
68 struct nfnl_subsys_handle *nfnlssh;
92 for (cur_gh = gh->h->gh_list; cur_gh; cur_gh = cur_gh->next) {
95 prev_gh->next = gh->next;
97 gh->h->gh_list = gh->next;
106 gh->next = gh->h->gh_list;
114 for (gh = h->gh_list; gh; gh = gh->next) {
123 __build_send_cfg_msg(
struct nflog_handle *h, uint8_t command,
124 uint16_t groupnum, uint8_t pf)
127 char buf[NFNL_HEADER_LEN
128 +NFA_LENGTH(
sizeof(
struct nfulnl_msg_config_cmd))];
131 struct nfulnl_msg_config_cmd cmd;
133 nfnl_fill_hdr(h->nfnlssh, &u.nmh, 0, pf, groupnum,
134 NFULNL_MSG_CONFIG, NLM_F_REQUEST|NLM_F_ACK);
136 cmd.command = command;
137 nfnl_addattr_l(&u.nmh,
sizeof(u), NFULA_CFG_CMD, &cmd,
sizeof(cmd));
139 return nfnl_query(h->nfnlh, &u.nmh);
142 static int __nflog_rcv_pkt(
struct nlmsghdr *nlh,
struct nfattr *nfa[],
145 struct nfgenmsg *nfmsg = NLMSG_DATA(nlh);
147 uint16_t group = ntohs(nfmsg->res_id);
149 struct nflog_data nfldata;
158 return gh->cb(gh, nfmsg, &nfldata, gh->data);
161 static struct nfnl_callback pkt_cb = {
162 .call = &__nflog_rcv_pkt,
163 .attr_count = NFULA_MAX,
229 return nfnl_fd(nflog_nfnlh(h));
236 struct nflog_handle *nflog_open_nfnl(
struct nfnl_handle *nfnlh)
241 h = malloc(
sizeof(*h));
245 memset(h, 0,
sizeof(*h));
248 h->nfnlssh = nfnl_subsys_open(h->nfnlh, NFNL_SUBSYS_ULOG,
256 err = nfnl_callback_register(h->nfnlssh, NFULNL_MSG_PACKET, &pkt_cb);
264 nfnl_close(h->nfnlh);
287 struct nfnl_handle *nfnlh;
297 nfnl_unset_sequence_tracking(nfnlh);
299 lh = nflog_open_nfnl(nfnlh);
310 int nflog_callback_register(
struct nflog_g_handle *gh, nflog_callback *cb,
319 int nflog_handle_packet(
struct nflog_handle *h,
char *buf,
int len)
321 return nfnl_handle_packet(h->nfnlh, buf, len);
343 int ret = nfnl_close(h->nfnlh);
360 return __build_send_cfg_msg(h, NFULNL_CFG_CMD_PF_BIND, 0, pf);
374 return __build_send_cfg_msg(h, NFULNL_CFG_CMD_PF_UNBIND, 0, pf);
401 gh = malloc(
sizeof(*gh));
405 memset(gh, 0,
sizeof(*gh));
409 if (__build_send_cfg_msg(h, NFULNL_CFG_CMD_BIND, num, 0) < 0) {
435 int ret = __build_send_cfg_msg(gh->h, NFULNL_CFG_CMD_UNBIND, gh->id, 0);
460 uint8_t mode, uint32_t range)
463 char buf[NFNL_HEADER_LEN
464 +NFA_LENGTH(
sizeof(
struct nfulnl_msg_config_mode))];
467 struct nfulnl_msg_config_mode params;
469 nfnl_fill_hdr(gh->h->nfnlssh, &u.nmh, 0, AF_UNSPEC, gh->id,
470 NFULNL_MSG_CONFIG, NLM_F_REQUEST|NLM_F_ACK);
472 params.copy_range = htonl(range);
473 params.copy_mode = mode;
474 nfnl_addattr_l(&u.nmh,
sizeof(u), NFULA_CFG_MODE, ¶ms,
477 return nfnl_query(gh->h->nfnlh, &u.nmh);
495 char buf[NFNL_HEADER_LEN+NFA_LENGTH(
sizeof(uint32_t))];
499 nfnl_fill_hdr(gh->h->nfnlssh, &u.nmh, 0, AF_UNSPEC, gh->id,
500 NFULNL_MSG_CONFIG, NLM_F_REQUEST|NLM_F_ACK);
502 nfnl_addattr32(&u.nmh,
sizeof(u), NFULA_CFG_TIMEOUT, htonl(timeout));
504 return nfnl_query(gh->h->nfnlh, &u.nmh);
520 char buf[NFNL_HEADER_LEN+NFA_LENGTH(
sizeof(uint32_t))];
524 nfnl_fill_hdr(gh->h->nfnlssh, &u.nmh, 0, AF_UNSPEC, gh->id,
525 NFULNL_MSG_CONFIG, NLM_F_REQUEST|NLM_F_ACK);
527 nfnl_addattr32(&u.nmh,
sizeof(u), NFULA_CFG_QTHRESH, htonl(qthresh));
529 return nfnl_query(gh->h->nfnlh, &u.nmh);
549 char buf[NFNL_HEADER_LEN+NFA_LENGTH(
sizeof(uint32_t))];
554 nfnl_fill_hdr(gh->h->nfnlssh, &u.nmh, 0, AF_UNSPEC, gh->id,
555 NFULNL_MSG_CONFIG, NLM_F_REQUEST|NLM_F_ACK);
557 nfnl_addattr32(&u.nmh,
sizeof(u), NFULA_CFG_NLBUFSIZ, htonl(nlbufsiz));
559 status = nfnl_query(gh->h->nfnlh, &u.nmh);
563 nfnl_rcvbufsiz(gh->h->nfnlh, 10*nlbufsiz);
583 char buf[NFNL_HEADER_LEN+NFA_LENGTH(
sizeof(uint16_t))];
587 nfnl_fill_hdr(gh->h->nfnlssh, &u.nmh, 0, AF_UNSPEC, gh->id,
588 NFULNL_MSG_CONFIG, NLM_F_REQUEST|NLM_F_ACK);
590 nfnl_addattr16(&u.nmh,
sizeof(u), NFULA_CFG_FLAGS, htons(flags));
592 return nfnl_query(gh->h->nfnlh, &u.nmh);
623 return nfnl_get_pointer_to_data(nfad->nfa, NFULA_PACKET_HDR,
624 struct nfulnl_msg_packet_hdr);
635 return ntohs(nfnl_get_data(nfad->nfa, NFULA_HWTYPE, uint16_t));
646 return ntohs(nfnl_get_data(nfad->nfa, NFULA_HWLEN, uint16_t));
657 return nfnl_get_pointer_to_data(nfad->nfa, NFULA_HWHEADER,
char);
668 return ntohl(nfnl_get_data(nfad->nfa, NFULA_MARK, uint32_t));
682 struct nfulnl_msg_packet_timestamp *uts;
684 uts = nfnl_get_pointer_to_data(nfad->nfa, NFULA_TIMESTAMP,
685 struct nfulnl_msg_packet_timestamp);
689 tv->tv_sec = __be64_to_cpu(uts->sec);
690 tv->tv_usec = __be64_to_cpu(uts->usec);
708 return ntohl(nfnl_get_data(nfad->nfa, NFULA_IFINDEX_INDEV, uint32_t));
721 return ntohl(nfnl_get_data(nfad->nfa, NFULA_IFINDEX_PHYSINDEV, uint32_t));
734 return ntohl(nfnl_get_data(nfad->nfa, NFULA_IFINDEX_OUTDEV, uint32_t));
750 return ntohl(nfnl_get_data(nfad->nfa, NFULA_IFINDEX_PHYSOUTDEV, uint32_t));
774 return nfnl_get_pointer_to_data(nfad->nfa, NFULA_HWADDR,
775 struct nfulnl_msg_packet_hw);
791 *data = nfnl_get_pointer_to_data(nfad->nfa, NFULA_PAYLOAD,
char);
793 return NFA_PAYLOAD(nfad->nfa[NFULA_PAYLOAD-1]);
807 return nfnl_get_pointer_to_data(nfad->nfa, NFULA_PREFIX,
char);
818 if (!nfnl_attr_present(nfad->nfa, NFULA_UID))
821 *uid = ntohl(nfnl_get_data(nfad->nfa, NFULA_UID, uint32_t));
833 if (!nfnl_attr_present(nfad->nfa, NFULA_GID))
836 *gid = ntohl(nfnl_get_data(nfad->nfa, NFULA_GID, uint32_t));
850 if (!nfnl_attr_present(nfad->nfa, NFULA_SEQ))
853 *seq = ntohl(nfnl_get_data(nfad->nfa, NFULA_SEQ, uint32_t));
867 if (!nfnl_attr_present(nfad->nfa, NFULA_SEQ_GLOBAL))
870 *seq = ntohl(nfnl_get_data(nfad->nfa, NFULA_SEQ_GLOBAL, uint32_t));
878 #define SNPRINTF_FAILURE(ret, rem, offset, len) \
920 struct nfulnl_msg_packet_hdr *ph;
921 struct nfulnl_msg_packet_hw *hwph;
923 int size, offset = 0, len = 0, ret;
926 size = snprintf(buf + offset, rem,
"<log>");
927 SNPRINTF_FAILURE(size, rem, offset, len);
929 if (flags & NFLOG_XML_TIME) {
934 if (localtime_r(&t, &tm) == NULL)
937 size = snprintf(buf + offset, rem,
"<when>");
938 SNPRINTF_FAILURE(size, rem, offset, len);
940 size = snprintf(buf + offset, rem,
941 "<hour>%d</hour>", tm.tm_hour);
942 SNPRINTF_FAILURE(size, rem, offset, len);
944 size = snprintf(buf + offset,
945 rem,
"<min>%02d</min>", tm.tm_min);
946 SNPRINTF_FAILURE(size, rem, offset, len);
948 size = snprintf(buf + offset,
949 rem,
"<sec>%02d</sec>", tm.tm_sec);
950 SNPRINTF_FAILURE(size, rem, offset, len);
952 size = snprintf(buf + offset, rem,
"<wday>%d</wday>",
954 SNPRINTF_FAILURE(size, rem, offset, len);
956 size = snprintf(buf + offset, rem,
"<day>%d</day>", tm.tm_mday);
957 SNPRINTF_FAILURE(size, rem, offset, len);
959 size = snprintf(buf + offset, rem,
"<month>%d</month>",
961 SNPRINTF_FAILURE(size, rem, offset, len);
963 size = snprintf(buf + offset, rem,
"<year>%d</year>",
965 SNPRINTF_FAILURE(size, rem, offset, len);
967 size = snprintf(buf + offset, rem,
"</when>");
968 SNPRINTF_FAILURE(size, rem, offset, len);
972 if (data && (flags & NFLOG_XML_PREFIX)) {
973 size = snprintf(buf + offset, rem,
"<prefix>%s</prefix>", data);
974 SNPRINTF_FAILURE(size, rem, offset, len);
979 size = snprintf(buf + offset, rem,
"<hook>%u</hook>", ph->hook);
980 SNPRINTF_FAILURE(size, rem, offset, len);
983 if (hwph && (flags & NFLOG_XML_HW)) {
984 int i, hlen = ntohs(hwph->hw_addrlen);
986 size = snprintf(buf + offset, rem,
"<hw><proto>%04x"
988 ntohs(ph->hw_protocol));
989 SNPRINTF_FAILURE(size, rem, offset, len);
991 size = snprintf(buf + offset, rem,
"<src>");
992 SNPRINTF_FAILURE(size, rem, offset, len);
994 for (i=0; i<hlen; i++) {
995 size = snprintf(buf + offset, rem,
"%02x",
997 SNPRINTF_FAILURE(size, rem, offset, len);
1000 size = snprintf(buf + offset, rem,
"</src></hw>");
1001 SNPRINTF_FAILURE(size, rem, offset, len);
1002 }
else if (flags & NFLOG_XML_HW) {
1003 size = snprintf(buf + offset, rem,
"<hw><proto>%04x"
1005 ntohs(ph->hw_protocol));
1006 SNPRINTF_FAILURE(size, rem, offset, len);
1011 if (mark && (flags & NFLOG_XML_MARK)) {
1012 size = snprintf(buf + offset, rem,
"<mark>%u</mark>", mark);
1013 SNPRINTF_FAILURE(size, rem, offset, len);
1017 if (ifi && (flags & NFLOG_XML_DEV)) {
1018 size = snprintf(buf + offset, rem,
"<indev>%u</indev>", ifi);
1019 SNPRINTF_FAILURE(size, rem, offset, len);
1023 if (ifi && (flags & NFLOG_XML_DEV)) {
1024 size = snprintf(buf + offset, rem,
"<outdev>%u</outdev>", ifi);
1025 SNPRINTF_FAILURE(size, rem, offset, len);
1029 if (ifi && (flags & NFLOG_XML_PHYSDEV)) {
1030 size = snprintf(buf + offset, rem,
1031 "<physindev>%u</physindev>", ifi);
1032 SNPRINTF_FAILURE(size, rem, offset, len);
1036 if (ifi && (flags & NFLOG_XML_PHYSDEV)) {
1037 size = snprintf(buf + offset, rem,
1038 "<physoutdev>%u</physoutdev>", ifi);
1039 SNPRINTF_FAILURE(size, rem, offset, len);
1043 if (ret >= 0 && (flags & NFLOG_XML_PAYLOAD)) {
1046 size = snprintf(buf + offset, rem,
"<payload>");
1047 SNPRINTF_FAILURE(size, rem, offset, len);
1049 for (i=0; i<ret; i++) {
1050 size = snprintf(buf + offset, rem,
"%02x",
1052 SNPRINTF_FAILURE(size, rem, offset, len);
1055 size = snprintf(buf + offset, rem,
"</payload>");
1056 SNPRINTF_FAILURE(size, rem, offset, len);
1059 size = snprintf(buf + offset, rem,
"</log>");
1060 SNPRINTF_FAILURE(size, rem, offset, len);
uint32_t nflog_get_outdev(struct nflog_data *nfad)
int nflog_get_timestamp(struct nflog_data *nfad, struct timeval *tv)
uint16_t nflog_get_hwtype(struct nflog_data *nfad)
int nflog_get_seq(struct nflog_data *nfad, uint32_t *seq)
struct nflog_handle * nflog_open(void)
int nflog_get_gid(struct nflog_data *nfad, uint32_t *gid)
int nflog_set_flags(struct nflog_g_handle *gh, uint16_t flags)
char * nflog_get_msg_packet_hwhdr(struct nflog_data *nfad)
int nflog_set_mode(struct nflog_g_handle *gh, uint8_t mode, uint32_t range)
uint32_t nflog_get_physoutdev(struct nflog_data *nfad)
int nflog_get_payload(struct nflog_data *nfad, char **data)
int nflog_set_timeout(struct nflog_g_handle *gh, uint32_t timeout)
int nflog_set_nlbufsiz(struct nflog_g_handle *gh, uint32_t nlbufsiz)
uint32_t nflog_get_indev(struct nflog_data *nfad)
int nflog_set_qthresh(struct nflog_g_handle *gh, uint32_t qthresh)
struct nfulnl_msg_packet_hw * nflog_get_packet_hw(struct nflog_data *nfad)
int nflog_unbind_pf(struct nflog_handle *h, uint16_t pf)
uint32_t nflog_get_nfmark(struct nflog_data *nfad)
struct nflog_g_handle * nflog_bind_group(struct nflog_handle *h, uint16_t num)
int nflog_get_seq_global(struct nflog_data *nfad, uint32_t *seq)
uint16_t nflog_get_msg_packet_hwhdrlen(struct nflog_data *nfad)
int nflog_bind_pf(struct nflog_handle *h, uint16_t pf)
int nflog_unbind_group(struct nflog_g_handle *gh)
int nflog_close(struct nflog_handle *h)
int nflog_get_uid(struct nflog_data *nfad, uint32_t *uid)
char * nflog_get_prefix(struct nflog_data *nfad)
int nflog_snprintf_xml(char *buf, size_t rem, struct nflog_data *tb, int flags)
int nflog_fd(struct nflog_handle *h)
uint32_t nflog_get_physindev(struct nflog_data *nfad)
struct nfulnl_msg_packet_hdr * nflog_get_msg_packet_hdr(struct nflog_data *nfad)