27 #include <netinet/in.h>
28 #include <sys/socket.h>
30 #include <libnetfilter_log/linux_nfnetlink_log.h>
32 #include <libnfnetlink/libnfnetlink.h>
33 #include <libnetfilter_log/libnetfilter_log.h>
66 struct nfnl_handle *nfnlh;
67 struct nfnl_subsys_handle *nfnlssh;
96 for (cur_gh = gh->h->gh_list; cur_gh; cur_gh = cur_gh->next) {
99 prev_gh->next = gh->next;
101 gh->h->gh_list = gh->next;
110 gh->next = gh->h->gh_list;
118 for (gh = h->gh_list; gh; gh = gh->next) {
127 __build_send_cfg_msg(
struct nflog_handle *h, u_int8_t command,
128 u_int16_t groupnum, u_int8_t pf)
131 char buf[NFNL_HEADER_LEN
132 +NFA_LENGTH(
sizeof(
struct nfulnl_msg_config_cmd))];
135 struct nfulnl_msg_config_cmd cmd;
137 nfnl_fill_hdr(h->nfnlssh, &u.nmh, 0, pf, groupnum,
138 NFULNL_MSG_CONFIG, NLM_F_REQUEST|NLM_F_ACK);
140 cmd.command = command;
141 nfnl_addattr_l(&u.nmh,
sizeof(u), NFULA_CFG_CMD, &cmd,
sizeof(cmd));
143 return nfnl_query(h->nfnlh, &u.nmh);
146 static int __nflog_rcv_pkt(
struct nlmsghdr *nlh,
struct nfattr *nfa[],
149 struct nfgenmsg *nfmsg = NLMSG_DATA(nlh);
151 u_int16_t group = ntohs(nfmsg->res_id);
162 return gh->cb(gh, nfmsg, &nfldata, gh->data);
165 static struct nfnl_callback pkt_cb = {
166 .call = &__nflog_rcv_pkt,
167 .attr_count = NFULA_MAX,
233 return nfnl_fd(nflog_nfnlh(h));
240 struct nflog_handle *nflog_open_nfnl(
struct nfnl_handle *nfnlh)
245 h = malloc(
sizeof(*h));
249 memset(h, 0,
sizeof(*h));
252 h->nfnlssh = nfnl_subsys_open(h->nfnlh, NFNL_SUBSYS_ULOG,
260 err = nfnl_callback_register(h->nfnlssh, NFULNL_MSG_PACKET, &pkt_cb);
268 nfnl_close(h->nfnlh);
291 struct nfnl_handle *nfnlh;
301 nfnl_unset_sequence_tracking(nfnlh);
303 lh = nflog_open_nfnl(nfnlh);
314 int nflog_callback_register(
struct nflog_g_handle *gh, nflog_callback *cb,
323 int nflog_handle_packet(
struct nflog_handle *h,
char *buf,
int len)
325 return nfnl_handle_packet(h->nfnlh, buf, len);
347 int ret = nfnl_close(h->nfnlh);
364 return __build_send_cfg_msg(h, NFULNL_CFG_CMD_PF_BIND, 0, pf);
378 return __build_send_cfg_msg(h, NFULNL_CFG_CMD_PF_UNBIND, 0, pf);
405 gh = malloc(
sizeof(*gh));
409 memset(gh, 0,
sizeof(*gh));
413 if (__build_send_cfg_msg(h, NFULNL_CFG_CMD_BIND, num, 0) < 0) {
439 int ret = __build_send_cfg_msg(gh->h, NFULNL_CFG_CMD_UNBIND, gh->id, 0);
464 u_int8_t mode, u_int32_t range)
467 char buf[NFNL_HEADER_LEN
468 +NFA_LENGTH(
sizeof(
struct nfulnl_msg_config_mode))];
471 struct nfulnl_msg_config_mode params;
473 nfnl_fill_hdr(gh->h->nfnlssh, &u.nmh, 0, AF_UNSPEC, gh->id,
474 NFULNL_MSG_CONFIG, NLM_F_REQUEST|NLM_F_ACK);
476 params.copy_range = htonl(range);
477 params.copy_mode = mode;
478 nfnl_addattr_l(&u.nmh,
sizeof(u), NFULA_CFG_MODE, ¶ms,
481 return nfnl_query(gh->h->nfnlh, &u.nmh);
499 char buf[NFNL_HEADER_LEN+NFA_LENGTH(
sizeof(u_int32_t))];
503 nfnl_fill_hdr(gh->h->nfnlssh, &u.nmh, 0, AF_UNSPEC, gh->id,
504 NFULNL_MSG_CONFIG, NLM_F_REQUEST|NLM_F_ACK);
506 nfnl_addattr32(&u.nmh,
sizeof(u), NFULA_CFG_TIMEOUT, htonl(timeout));
508 return nfnl_query(gh->h->nfnlh, &u.nmh);
524 char buf[NFNL_HEADER_LEN+NFA_LENGTH(
sizeof(u_int32_t))];
528 nfnl_fill_hdr(gh->h->nfnlssh, &u.nmh, 0, AF_UNSPEC, gh->id,
529 NFULNL_MSG_CONFIG, NLM_F_REQUEST|NLM_F_ACK);
531 nfnl_addattr32(&u.nmh,
sizeof(u), NFULA_CFG_QTHRESH, htonl(qthresh));
533 return nfnl_query(gh->h->nfnlh, &u.nmh);
553 char buf[NFNL_HEADER_LEN+NFA_LENGTH(
sizeof(u_int32_t))];
558 nfnl_fill_hdr(gh->h->nfnlssh, &u.nmh, 0, AF_UNSPEC, gh->id,
559 NFULNL_MSG_CONFIG, NLM_F_REQUEST|NLM_F_ACK);
561 nfnl_addattr32(&u.nmh,
sizeof(u), NFULA_CFG_NLBUFSIZ, htonl(nlbufsiz));
563 status = nfnl_query(gh->h->nfnlh, &u.nmh);
567 nfnl_rcvbufsiz(gh->h->nfnlh, 10*nlbufsiz);
587 char buf[NFNL_HEADER_LEN+NFA_LENGTH(
sizeof(u_int16_t))];
591 nfnl_fill_hdr(gh->h->nfnlssh, &u.nmh, 0, AF_UNSPEC, gh->id,
592 NFULNL_MSG_CONFIG, NLM_F_REQUEST|NLM_F_ACK);
594 nfnl_addattr16(&u.nmh,
sizeof(u), NFULA_CFG_FLAGS, htons(flags));
596 return nfnl_query(gh->h->nfnlh, &u.nmh);
627 return nfnl_get_pointer_to_data(nfad->nfa, NFULA_PACKET_HDR,
628 struct nfulnl_msg_packet_hdr);
639 return ntohs(nfnl_get_data(nfad->nfa, NFULA_HWTYPE, u_int16_t));
650 return ntohs(nfnl_get_data(nfad->nfa, NFULA_HWLEN, u_int16_t));
661 return nfnl_get_pointer_to_data(nfad->nfa, NFULA_HWHEADER,
char);
672 return ntohl(nfnl_get_data(nfad->nfa, NFULA_MARK, u_int32_t));
686 struct nfulnl_msg_packet_timestamp *uts;
688 uts = nfnl_get_pointer_to_data(nfad->nfa, NFULA_TIMESTAMP,
689 struct nfulnl_msg_packet_timestamp);
693 tv->tv_sec = __be64_to_cpu(uts->sec);
694 tv->tv_usec = __be64_to_cpu(uts->usec);
712 return ntohl(nfnl_get_data(nfad->nfa, NFULA_IFINDEX_INDEV, u_int32_t));
725 return ntohl(nfnl_get_data(nfad->nfa, NFULA_IFINDEX_PHYSINDEV, u_int32_t));
738 return ntohl(nfnl_get_data(nfad->nfa, NFULA_IFINDEX_OUTDEV, u_int32_t));
754 return ntohl(nfnl_get_data(nfad->nfa, NFULA_IFINDEX_PHYSOUTDEV, u_int32_t));
778 return nfnl_get_pointer_to_data(nfad->nfa, NFULA_HWADDR,
779 struct nfulnl_msg_packet_hw);
795 *data = nfnl_get_pointer_to_data(nfad->nfa, NFULA_PAYLOAD,
char);
797 return NFA_PAYLOAD(nfad->nfa[NFULA_PAYLOAD-1]);
811 return nfnl_get_pointer_to_data(nfad->nfa, NFULA_PREFIX,
char);
822 if (!nfnl_attr_present(nfad->nfa, NFULA_UID))
825 *uid = ntohl(nfnl_get_data(nfad->nfa, NFULA_UID, u_int32_t));
837 if (!nfnl_attr_present(nfad->nfa, NFULA_GID))
840 *gid = ntohl(nfnl_get_data(nfad->nfa, NFULA_GID, u_int32_t));
854 if (!nfnl_attr_present(nfad->nfa, NFULA_SEQ))
857 *seq = ntohl(nfnl_get_data(nfad->nfa, NFULA_SEQ, u_int32_t));
871 if (!nfnl_attr_present(nfad->nfa, NFULA_SEQ_GLOBAL))
874 *seq = ntohl(nfnl_get_data(nfad->nfa, NFULA_SEQ_GLOBAL, u_int32_t));
882 #define SNPRINTF_FAILURE(ret, rem, offset, len) \
924 struct nfulnl_msg_packet_hdr *ph;
925 struct nfulnl_msg_packet_hw *hwph;
927 int size, offset = 0, len = 0, ret;
930 size = snprintf(buf + offset, rem,
"<log>");
931 SNPRINTF_FAILURE(size, rem, offset, len);
933 if (flags & NFLOG_XML_TIME) {
938 if (localtime_r(&t, &tm) == NULL)
941 size = snprintf(buf + offset, rem,
"<when>");
942 SNPRINTF_FAILURE(size, rem, offset, len);
944 size = snprintf(buf + offset, rem,
945 "<hour>%d</hour>", tm.tm_hour);
946 SNPRINTF_FAILURE(size, rem, offset, len);
948 size = snprintf(buf + offset,
949 rem,
"<min>%02d</min>", tm.tm_min);
950 SNPRINTF_FAILURE(size, rem, offset, len);
952 size = snprintf(buf + offset,
953 rem,
"<sec>%02d</sec>", tm.tm_sec);
954 SNPRINTF_FAILURE(size, rem, offset, len);
956 size = snprintf(buf + offset, rem,
"<wday>%d</wday>",
958 SNPRINTF_FAILURE(size, rem, offset, len);
960 size = snprintf(buf + offset, rem,
"<day>%d</day>", tm.tm_mday);
961 SNPRINTF_FAILURE(size, rem, offset, len);
963 size = snprintf(buf + offset, rem,
"<month>%d</month>",
965 SNPRINTF_FAILURE(size, rem, offset, len);
967 size = snprintf(buf + offset, rem,
"<year>%d</year>",
969 SNPRINTF_FAILURE(size, rem, offset, len);
971 size = snprintf(buf + offset, rem,
"</when>");
972 SNPRINTF_FAILURE(size, rem, offset, len);
976 if (data && (flags & NFLOG_XML_PREFIX)) {
977 size = snprintf(buf + offset, rem,
"<prefix>%s</prefix>", data);
978 SNPRINTF_FAILURE(size, rem, offset, len);
983 size = snprintf(buf + offset, rem,
"<hook>%u</hook>", ph->hook);
984 SNPRINTF_FAILURE(size, rem, offset, len);
987 if (hwph && (flags & NFLOG_XML_HW)) {
988 int i, hlen = ntohs(hwph->hw_addrlen);
990 size = snprintf(buf + offset, rem,
"<hw><proto>%04x"
992 ntohs(ph->hw_protocol));
993 SNPRINTF_FAILURE(size, rem, offset, len);
995 size = snprintf(buf + offset, rem,
"<src>");
996 SNPRINTF_FAILURE(size, rem, offset, len);
998 for (i=0; i<hlen; i++) {
999 size = snprintf(buf + offset, rem,
"%02x",
1001 SNPRINTF_FAILURE(size, rem, offset, len);
1004 size = snprintf(buf + offset, rem,
"</src></hw>");
1005 SNPRINTF_FAILURE(size, rem, offset, len);
1006 }
else if (flags & NFLOG_XML_HW) {
1007 size = snprintf(buf + offset, rem,
"<hw><proto>%04x"
1009 ntohs(ph->hw_protocol));
1010 SNPRINTF_FAILURE(size, rem, offset, len);
1015 if (mark && (flags & NFLOG_XML_MARK)) {
1016 size = snprintf(buf + offset, rem,
"<mark>%u</mark>", mark);
1017 SNPRINTF_FAILURE(size, rem, offset, len);
1021 if (ifi && (flags & NFLOG_XML_DEV)) {
1022 size = snprintf(buf + offset, rem,
"<indev>%u</indev>", ifi);
1023 SNPRINTF_FAILURE(size, rem, offset, len);
1027 if (ifi && (flags & NFLOG_XML_DEV)) {
1028 size = snprintf(buf + offset, rem,
"<outdev>%u</outdev>", ifi);
1029 SNPRINTF_FAILURE(size, rem, offset, len);
1033 if (ifi && (flags & NFLOG_XML_PHYSDEV)) {
1034 size = snprintf(buf + offset, rem,
1035 "<physindev>%u</physindev>", ifi);
1036 SNPRINTF_FAILURE(size, rem, offset, len);
1040 if (ifi && (flags & NFLOG_XML_PHYSDEV)) {
1041 size = snprintf(buf + offset, rem,
1042 "<physoutdev>%u</physoutdev>", ifi);
1043 SNPRINTF_FAILURE(size, rem, offset, len);
1047 if (ret >= 0 && (flags & NFLOG_XML_PAYLOAD)) {
1050 size = snprintf(buf + offset, rem,
"<payload>");
1051 SNPRINTF_FAILURE(size, rem, offset, len);
1053 for (i=0; i<ret; i++) {
1054 size = snprintf(buf + offset, rem,
"%02x",
1056 SNPRINTF_FAILURE(size, rem, offset, len);
1059 size = snprintf(buf + offset, rem,
"</payload>");
1060 SNPRINTF_FAILURE(size, rem, offset, len);
1063 size = snprintf(buf + offset, rem,
"</log>");
1064 SNPRINTF_FAILURE(size, rem, offset, len);
int nflog_bind_pf(struct nflog_handle *h, u_int16_t pf)
struct nflog_handle * nflog_open(void)
int nflog_unbind_pf(struct nflog_handle *h, u_int16_t pf)
int nflog_close(struct nflog_handle *h)
int nflog_set_timeout(struct nflog_g_handle *gh, u_int32_t timeout)
int nflog_set_mode(struct nflog_g_handle *gh, u_int8_t mode, u_int32_t range)
int nflog_set_qthresh(struct nflog_g_handle *gh, u_int32_t qthresh)
struct nflog_g_handle * nflog_bind_group(struct nflog_handle *h, u_int16_t num)
int nflog_set_flags(struct nflog_g_handle *gh, u_int16_t flags)
int nflog_fd(struct nflog_handle *h)
int nflog_set_nlbufsiz(struct nflog_g_handle *gh, u_int32_t nlbufsiz)
int nflog_unbind_group(struct nflog_g_handle *gh)
u_int32_t nflog_get_physindev(struct nflog_data *nfad)
u_int32_t nflog_get_nfmark(struct nflog_data *nfad)
int nflog_get_uid(struct nflog_data *nfad, u_int32_t *uid)
struct nfulnl_msg_packet_hw * nflog_get_packet_hw(struct nflog_data *nfad)
int nflog_get_seq_global(struct nflog_data *nfad, u_int32_t *seq)
int nflog_get_seq(struct nflog_data *nfad, u_int32_t *seq)
u_int16_t nflog_get_hwtype(struct nflog_data *nfad)
u_int16_t nflog_get_msg_packet_hwhdrlen(struct nflog_data *nfad)
char * nflog_get_prefix(struct nflog_data *nfad)
int nflog_get_gid(struct nflog_data *nfad, u_int32_t *gid)
struct nfulnl_msg_packet_hdr * nflog_get_msg_packet_hdr(struct nflog_data *nfad)
u_int32_t nflog_get_physoutdev(struct nflog_data *nfad)
u_int32_t nflog_get_indev(struct nflog_data *nfad)
int nflog_get_payload(struct nflog_data *nfad, char **data)
u_int32_t nflog_get_outdev(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)