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>
36 #include <libmnl/libmnl.h>
37 #include <linux/netfilter/nfnetlink_conntrack.h>
70 struct nfnl_handle *nfnlh;
71 struct nfnl_subsys_handle *nfnlssh;
72 struct nflog_g_handle *gh_list;
77 struct nflog_g_handle *next;
78 struct nflog_handle *h;
91 static void del_gh(
struct nflog_g_handle *gh)
93 struct nflog_g_handle *cur_gh, *prev_gh = NULL;
95 for (cur_gh = gh->h->gh_list; cur_gh; cur_gh = cur_gh->next) {
98 prev_gh->next = gh->next;
100 gh->h->gh_list = gh->next;
107 static void add_gh(
struct nflog_g_handle *gh)
109 gh->next = gh->h->gh_list;
113 static struct nflog_g_handle *find_gh(
struct nflog_handle *h, uint16_t group)
115 struct nflog_g_handle *gh;
117 for (gh = h->gh_list; gh; gh = gh->next) {
126 __build_send_cfg_msg(
struct nflog_handle *h, uint8_t command,
127 uint16_t groupnum, uint8_t pf)
130 char buf[NFNL_HEADER_LEN
131 +NFA_LENGTH(
sizeof(
struct nfulnl_msg_config_cmd))];
134 struct nfulnl_msg_config_cmd cmd;
136 nfnl_fill_hdr(h->nfnlssh, &u.nmh, 0, pf, groupnum,
137 NFULNL_MSG_CONFIG, NLM_F_REQUEST|NLM_F_ACK);
139 cmd.command = command;
140 nfnl_addattr_l(&u.nmh,
sizeof(u), NFULA_CFG_CMD, &cmd,
sizeof(cmd));
142 return nfnl_query(h->nfnlh, &u.nmh);
145 static int __nflog_rcv_pkt(
struct nlmsghdr *nlh,
struct nfattr *nfa[],
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;
161 return gh->cb(gh, nfmsg, &nfldata, gh->data);
164 static struct nfnl_callback pkt_cb = {
165 .call = &__nflog_rcv_pkt,
166 .attr_count = NFULA_MAX,
171 struct nfnl_handle *nflog_nfnlh(
struct nflog_handle *h)
247 return nfnl_fd(nflog_nfnlh(h));
254 struct nflog_handle *nflog_open_nfnl(
struct nfnl_handle *nfnlh)
256 struct nflog_handle *h;
259 h = calloc(1,
sizeof(*h));
265 h->nfnlssh = nfnl_subsys_open(h->nfnlh, NFNL_SUBSYS_ULOG,
273 err = nfnl_callback_register(h->nfnlssh, NFULNL_MSG_PACKET, &pkt_cb);
281 nfnl_close(h->nfnlh);
306 struct nfnl_handle *nfnlh;
307 struct nflog_handle *lh;
316 nfnl_unset_sequence_tracking(nfnlh);
318 lh = nflog_open_nfnl(nfnlh);
368 return nfnl_handle_packet(h->nfnlh, buf, len);
403 int ret = nfnl_close(h->nfnlh);
422 return __build_send_cfg_msg(h, NFULNL_CFG_CMD_PF_BIND, 0, pf);
439 return __build_send_cfg_msg(h, NFULNL_CFG_CMD_PF_UNBIND, 0, pf);
463 struct nflog_g_handle *
466 struct nflog_g_handle *gh;
468 if (find_gh(h, num)) {
473 gh = calloc(1,
sizeof(*gh));
480 if (__build_send_cfg_msg(h, NFULNL_CFG_CMD_BIND, num, 0) < 0) {
508 int ret = __build_send_cfg_msg(gh->h, NFULNL_CFG_CMD_UNBIND, gh->id, 0);
535 uint8_t mode, uint32_t range)
538 char buf[NFNL_HEADER_LEN
539 +NFA_LENGTH(
sizeof(
struct nfulnl_msg_config_mode))];
542 struct nfulnl_msg_config_mode params;
544 nfnl_fill_hdr(gh->h->nfnlssh, &u.nmh, 0, AF_UNSPEC, gh->id,
545 NFULNL_MSG_CONFIG, NLM_F_REQUEST|NLM_F_ACK);
547 params.copy_range = htonl(range);
548 params.copy_mode = mode;
549 nfnl_addattr_l(&u.nmh,
sizeof(u), NFULA_CFG_MODE, ¶ms,
552 return nfnl_query(gh->h->nfnlh, &u.nmh);
572 char buf[NFNL_HEADER_LEN+NFA_LENGTH(
sizeof(uint32_t))];
576 nfnl_fill_hdr(gh->h->nfnlssh, &u.nmh, 0, AF_UNSPEC, gh->id,
577 NFULNL_MSG_CONFIG, NLM_F_REQUEST|NLM_F_ACK);
579 nfnl_addattr32(&u.nmh,
sizeof(u), NFULA_CFG_TIMEOUT, htonl(timeout));
581 return nfnl_query(gh->h->nfnlh, &u.nmh);
599 char buf[NFNL_HEADER_LEN+NFA_LENGTH(
sizeof(uint32_t))];
603 nfnl_fill_hdr(gh->h->nfnlssh, &u.nmh, 0, AF_UNSPEC, gh->id,
604 NFULNL_MSG_CONFIG, NLM_F_REQUEST|NLM_F_ACK);
606 nfnl_addattr32(&u.nmh,
sizeof(u), NFULA_CFG_QTHRESH, htonl(qthresh));
608 return nfnl_query(gh->h->nfnlh, &u.nmh);
630 char buf[NFNL_HEADER_LEN+NFA_LENGTH(
sizeof(uint32_t))];
635 nfnl_fill_hdr(gh->h->nfnlssh, &u.nmh, 0, AF_UNSPEC, gh->id,
636 NFULNL_MSG_CONFIG, NLM_F_REQUEST|NLM_F_ACK);
638 nfnl_addattr32(&u.nmh,
sizeof(u), NFULA_CFG_NLBUFSIZ, htonl(nlbufsiz));
640 status = nfnl_query(gh->h->nfnlh, &u.nmh);
644 nfnl_rcvbufsiz(gh->h->nfnlh, 10*nlbufsiz);
667 char buf[NFNL_HEADER_LEN+NFA_LENGTH(
sizeof(uint16_t))];
671 nfnl_fill_hdr(gh->h->nfnlssh, &u.nmh, 0, AF_UNSPEC, gh->id,
672 NFULNL_MSG_CONFIG, NLM_F_REQUEST|NLM_F_ACK);
674 nfnl_addattr16(&u.nmh,
sizeof(u), NFULA_CFG_FLAGS, htons(flags));
676 return nfnl_query(gh->h->nfnlh, &u.nmh);
714 return nfnl_get_pointer_to_data(nfad->nfa, NFULA_PACKET_HDR,
715 struct nfulnl_msg_packet_hdr);
726 return ntohs(nfnl_get_data(nfad->nfa, NFULA_HWTYPE, uint16_t));
737 return ntohs(nfnl_get_data(nfad->nfa, NFULA_HWLEN, uint16_t));
748 return nfnl_get_pointer_to_data(nfad->nfa, NFULA_HWHEADER,
char);
759 return ntohl(nfnl_get_data(nfad->nfa, NFULA_MARK, uint32_t));
775 struct nfulnl_msg_packet_timestamp *uts;
777 uts = nfnl_get_pointer_to_data(nfad->nfa, NFULA_TIMESTAMP,
778 struct nfulnl_msg_packet_timestamp);
782 tv->tv_sec = __be64_to_cpu(uts->sec);
783 tv->tv_usec = __be64_to_cpu(uts->usec);
801 return ntohl(nfnl_get_data(nfad->nfa, NFULA_IFINDEX_INDEV, uint32_t));
815 return ntohl(nfnl_get_data(nfad->nfa, NFULA_IFINDEX_PHYSINDEV, uint32_t));
828 return ntohl(nfnl_get_data(nfad->nfa, NFULA_IFINDEX_OUTDEV, uint32_t));
841 return ntohl(nfnl_get_data(nfad->nfa, NFULA_IFINDEX_PHYSOUTDEV, uint32_t));
869 return nfnl_get_pointer_to_data(nfad->nfa, NFULA_HWADDR,
870 struct nfulnl_msg_packet_hw);
886 *data = nfnl_get_pointer_to_data(nfad->nfa, NFULA_PAYLOAD,
char);
888 return NFA_PAYLOAD(nfad->nfa[NFULA_PAYLOAD-1]);
902 return nfnl_get_pointer_to_data(nfad->nfa, NFULA_PREFIX,
char);
916 if (!nfnl_attr_present(nfad->nfa, NFULA_UID))
919 *uid = ntohl(nfnl_get_data(nfad->nfa, NFULA_UID, uint32_t));
934 if (!nfnl_attr_present(nfad->nfa, NFULA_GID))
937 *gid = ntohl(nfnl_get_data(nfad->nfa, NFULA_GID, uint32_t));
954 if (!nfnl_attr_present(nfad->nfa, NFULA_SEQ))
957 *seq = ntohl(nfnl_get_data(nfad->nfa, NFULA_SEQ, uint32_t));
974 if (!nfnl_attr_present(nfad->nfa, NFULA_SEQ_GLOBAL))
977 *seq = ntohl(nfnl_get_data(nfad->nfa, NFULA_SEQ_GLOBAL, uint32_t));
992 struct nlattr *cta = (
struct nlattr *)nfad->nfa[NFULA_CT - 1];
993 struct nlattr *attr, *ida = NULL;
998 mnl_attr_for_each_nested(attr, cta) {
999 if (mnl_attr_get_type(attr) == CTA_ID) {
1005 if (!ida || mnl_attr_validate(ida, MNL_TYPE_U32) < 0)
1008 *
id = ntohl(mnl_attr_get_u32(ida));
1017 #define SNPRINTF_FAILURE(ret, rem, offset, len) \
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;
1074 size = snprintf(buf + offset, rem,
"<log>");
1075 SNPRINTF_FAILURE(size, rem, offset, len);
1077 if (flags & NFLOG_XML_TIME) {
1082 if (localtime_r(&t, &tm) == NULL)
1085 size = snprintf(buf + offset, rem,
"<when>");
1086 SNPRINTF_FAILURE(size, rem, offset, len);
1088 size = snprintf(buf + offset, rem,
1089 "<hour>%d</hour>", tm.tm_hour);
1090 SNPRINTF_FAILURE(size, rem, offset, len);
1092 size = snprintf(buf + offset,
1093 rem,
"<min>%02d</min>", tm.tm_min);
1094 SNPRINTF_FAILURE(size, rem, offset, len);
1096 size = snprintf(buf + offset,
1097 rem,
"<sec>%02d</sec>", tm.tm_sec);
1098 SNPRINTF_FAILURE(size, rem, offset, len);
1100 size = snprintf(buf + offset, rem,
"<wday>%d</wday>",
1102 SNPRINTF_FAILURE(size, rem, offset, len);
1104 size = snprintf(buf + offset, rem,
"<day>%d</day>", tm.tm_mday);
1105 SNPRINTF_FAILURE(size, rem, offset, len);
1107 size = snprintf(buf + offset, rem,
"<month>%d</month>",
1109 SNPRINTF_FAILURE(size, rem, offset, len);
1111 size = snprintf(buf + offset, rem,
"<year>%d</year>",
1113 SNPRINTF_FAILURE(size, rem, offset, len);
1115 size = snprintf(buf + offset, rem,
"</when>");
1116 SNPRINTF_FAILURE(size, rem, offset, len);
1120 if (data && (flags & NFLOG_XML_PREFIX)) {
1121 size = snprintf(buf + offset, rem,
"<prefix>%s</prefix>", data);
1122 SNPRINTF_FAILURE(size, rem, offset, len);
1127 size = snprintf(buf + offset, rem,
"<hook>%u</hook>", ph->hook);
1128 SNPRINTF_FAILURE(size, rem, offset, len);
1131 if (hwph && (flags & NFLOG_XML_HW)) {
1132 int i, hlen = ntohs(hwph->hw_addrlen);
1134 size = snprintf(buf + offset, rem,
"<hw><proto>%04x"
1136 ntohs(ph->hw_protocol));
1137 SNPRINTF_FAILURE(size, rem, offset, len);
1139 size = snprintf(buf + offset, rem,
"<src>");
1140 SNPRINTF_FAILURE(size, rem, offset, len);
1142 for (i=0; i<hlen; i++) {
1143 size = snprintf(buf + offset, rem,
"%02x",
1145 SNPRINTF_FAILURE(size, rem, offset, len);
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"
1153 ntohs(ph->hw_protocol));
1154 SNPRINTF_FAILURE(size, rem, offset, len);
1159 if (mark && (flags & NFLOG_XML_MARK)) {
1160 size = snprintf(buf + offset, rem,
"<mark>%u</mark>", mark);
1161 SNPRINTF_FAILURE(size, rem, offset, len);
1165 if (ifi && (flags & NFLOG_XML_DEV)) {
1166 size = snprintf(buf + offset, rem,
"<indev>%u</indev>", ifi);
1167 SNPRINTF_FAILURE(size, rem, offset, len);
1171 if (ifi && (flags & NFLOG_XML_DEV)) {
1172 size = snprintf(buf + offset, rem,
"<outdev>%u</outdev>", ifi);
1173 SNPRINTF_FAILURE(size, rem, offset, len);
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);
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);
1190 if (flags & NFLOG_XML_CTID) {
1193 size = snprintf(buf + offset, rem,
1194 "<ctid>%u</ctid>", ctid);
1195 SNPRINTF_FAILURE(size, rem, offset, len);
1200 if (ret >= 0 && (flags & NFLOG_XML_PAYLOAD)) {
1203 size = snprintf(buf + offset, rem,
"<payload>");
1204 SNPRINTF_FAILURE(size, rem, offset, len);
1206 for (i=0; i<ret; i++) {
1207 size = snprintf(buf + offset, rem,
"%02x",
1209 SNPRINTF_FAILURE(size, rem, offset, len);
1212 size = snprintf(buf + offset, rem,
"</payload>");
1213 SNPRINTF_FAILURE(size, rem, offset, len);
1216 size = snprintf(buf + offset, rem,
"</log>");
1217 SNPRINTF_FAILURE(size, rem, offset, len);
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)