30 #include <netinet/in.h>
31 #include <sys/socket.h>
33 #include <libnfnetlink/libnfnetlink.h>
34 #include <libnetfilter_queue/libnetfilter_queue.h>
117 struct nfnl_handle *nfnlh;
118 struct nfnl_subsys_handle *nfnlssh;
133 struct nfattr **data;
137 EXPORT_SYMBOL(nfq_errno);
147 for (cur_qh = qh->h->qh_list; cur_qh; cur_qh = cur_qh->next) {
150 prev_qh->next = qh->next;
152 qh->h->qh_list = qh->next;
161 qh->next = qh->h->qh_list;
169 for (qh = h->qh_list; qh; qh = qh->next) {
178 __build_send_cfg_msg(
struct nfq_handle *h, uint8_t command,
179 uint16_t queuenum, uint16_t pf)
182 char buf[NFNL_HEADER_LEN
183 +NFA_LENGTH(
sizeof(
struct nfqnl_msg_config_cmd))];
186 struct nfqnl_msg_config_cmd cmd;
188 nfnl_fill_hdr(h->nfnlssh, &u.nmh, 0, AF_UNSPEC, queuenum,
189 NFQNL_MSG_CONFIG, NLM_F_REQUEST|NLM_F_ACK);
192 cmd.command = command;
194 nfnl_addattr_l(&u.nmh,
sizeof(u), NFQA_CFG_CMD, &cmd,
sizeof(cmd));
196 return nfnl_query(h->nfnlh, &u.nmh);
199 static int __nfq_rcv_pkt(
struct nlmsghdr *nlh,
struct nfattr *nfa[],
202 struct nfgenmsg *nfmsg = NLMSG_DATA(nlh);
204 uint16_t queue_num = ntohs(nfmsg->res_id);
216 return qh->cb(qh, nfmsg, &nfqa, qh->data);
221 struct nfnl_handle *nfq_nfnlh(
struct nfq_handle *h)
225 EXPORT_SYMBOL(nfq_nfnlh);
299 return nfnl_fd(nfq_nfnlh(h));
354 struct nfnl_handle *nfnlh = nfnl_open();
361 nfnl_unset_sequence_tracking(nfnlh);
363 qh = nfq_open_nfnl(nfnlh);
385 struct nfq_handle *nfq_open_nfnl(
struct nfnl_handle *nfnlh)
387 struct nfnl_callback pkt_cb = {
388 .call = __nfq_rcv_pkt,
389 .attr_count = NFQA_MAX,
394 h = malloc(
sizeof(*h));
398 memset(h, 0,
sizeof(*h));
401 h->nfnlssh = nfnl_subsys_open(h->nfnlh, NFNL_SUBSYS_QUEUE,
409 err = nfnl_callback_register(h->nfnlssh, NFQNL_MSG_PACKET, &pkt_cb);
417 nfnl_subsys_close(h->nfnlssh);
422 EXPORT_SYMBOL(nfq_open_nfnl);
445 ret = nfnl_close(h->nfnlh);
465 return __build_send_cfg_msg(h, NFQNL_CFG_CMD_PF_BIND, 0, pf);
481 return __build_send_cfg_msg(h, NFQNL_CFG_CMD_PF_UNBIND, 0, pf);
538 qh = malloc(
sizeof(*qh));
542 memset(qh, 0,
sizeof(*qh));
548 ret = __build_send_cfg_msg(h, NFQNL_CFG_CMD_BIND, num, 0);
578 int ret = __build_send_cfg_msg(qh->h, NFQNL_CFG_CMD_UNBIND, qh->id, 0);
602 return nfnl_handle_packet(h->nfnlh, buf, len);
622 uint8_t mode, uint32_t range)
625 char buf[NFNL_HEADER_LEN
626 +NFA_LENGTH(
sizeof(
struct nfqnl_msg_config_params))];
629 struct nfqnl_msg_config_params params;
631 nfnl_fill_hdr(qh->h->nfnlssh, &u.nmh, 0, AF_UNSPEC, qh->id,
632 NFQNL_MSG_CONFIG, NLM_F_REQUEST|NLM_F_ACK);
634 params.copy_range = htonl(range);
635 params.copy_mode = mode;
636 nfnl_addattr_l(&u.nmh,
sizeof(u), NFQA_CFG_PARAMS, ¶ms,
639 return nfnl_query(qh->h->nfnlh, &u.nmh);
712 uint32_t mask, uint32_t flags)
715 char buf[NFNL_HEADER_LEN
716 +NFA_LENGTH(
sizeof(mask)
717 +NFA_LENGTH(
sizeof(flags)))];
722 flags = htonl(flags);
724 nfnl_fill_hdr(qh->h->nfnlssh, &u.nmh, 0, AF_UNSPEC, qh->id,
725 NFQNL_MSG_CONFIG, NLM_F_REQUEST|NLM_F_ACK);
727 nfnl_addattr32(&u.nmh,
sizeof(u), NFQA_CFG_FLAGS, flags);
728 nfnl_addattr32(&u.nmh,
sizeof(u), NFQA_CFG_MASK, mask);
730 return nfnl_query(qh->h->nfnlh, &u.nmh);
749 char buf[NFNL_HEADER_LEN
750 +NFA_LENGTH(
sizeof(
struct nfqnl_msg_config_params))];
753 uint32_t queue_maxlen = htonl(queuelen);
755 nfnl_fill_hdr(qh->h->nfnlssh, &u.nmh, 0, AF_UNSPEC, qh->id,
756 NFQNL_MSG_CONFIG, NLM_F_REQUEST|NLM_F_ACK);
758 nfnl_addattr_l(&u.nmh,
sizeof(u), NFQA_CFG_QUEUE_MAXLEN, &queue_maxlen,
759 sizeof(queue_maxlen));
761 return nfnl_query(qh->h->nfnlh, &u.nmh);
769 static int __set_verdict(
struct nfq_q_handle *qh, uint32_t
id,
770 uint32_t verdict, uint32_t mark,
int set_mark,
771 uint32_t data_len,
const unsigned char *data,
772 enum nfqnl_msg_types type)
774 struct nfqnl_msg_verdict_hdr vh;
776 char buf[NFNL_HEADER_LEN
777 +NFA_LENGTH(
sizeof(mark))
778 +NFA_LENGTH(
sizeof(vh))];
787 struct nfattr data_attr;
789 memset(iov, 0,
sizeof(iov));
791 vh.verdict = htonl(verdict);
794 nfnl_fill_hdr(qh->h->nfnlssh, &u.nmh, 0, AF_UNSPEC, qh->id,
795 type, NLM_F_REQUEST);
798 nfnl_addattr_l(&u.nmh,
sizeof(u), NFQA_VERDICT_HDR, &vh,
sizeof(vh));
801 nfnl_addattr32(&u.nmh,
sizeof(u), NFQA_MARK, mark);
803 iov[0].iov_base = &u.nmh;
804 iov[0].iov_len = NLMSG_TAIL(&u.nmh) - (
void *)&u.nmh;
809 nfnl_build_nfa_iovec(&iov[1], &data_attr, NFQA_PAYLOAD,
810 data_len, (
unsigned char *) data);
816 u.nmh.nlmsg_len += data_attr.nfa_len;
819 return nfnl_sendiov(qh->h->nfnlh, iov, nvecs, 0);
851 uint32_t verdict, uint32_t data_len,
852 const unsigned char *buf)
854 return __set_verdict(qh,
id, verdict, 0, 0, data_len, buf,
869 uint32_t verdict, uint32_t mark,
870 uint32_t data_len,
const unsigned char *buf)
872 return __set_verdict(qh,
id, verdict, htonl(mark), 1, data_len,
873 buf, NFQNL_MSG_VERDICT);
892 return __set_verdict(qh,
id, verdict, 0, 0, 0, NULL,
893 NFQNL_MSG_VERDICT_BATCH);
905 uint32_t verdict, uint32_t mark)
907 return __set_verdict(qh,
id, verdict, htonl(mark), 1, 0,
908 NULL, NFQNL_MSG_VERDICT_BATCH);
927 uint32_t verdict, uint32_t mark,
928 uint32_t data_len,
const unsigned char *buf)
930 return __set_verdict(qh,
id, verdict, mark, 1, data_len, buf,
970 return nfnl_get_pointer_to_data(nfad->data, NFQA_PACKET_HDR,
971 struct nfqnl_msg_packet_hdr);
983 return ntohl(nfnl_get_data(nfad->data, NFQA_MARK, uint32_t));
998 struct nfqnl_msg_packet_timestamp *qpt;
999 qpt = nfnl_get_pointer_to_data(nfad->data, NFQA_TIMESTAMP,
1000 struct nfqnl_msg_packet_timestamp);
1004 tv->tv_sec = __be64_to_cpu(qpt->sec);
1005 tv->tv_usec = __be64_to_cpu(qpt->usec);
1024 return ntohl(nfnl_get_data(nfad->data, NFQA_IFINDEX_INDEV, uint32_t));
1038 return ntohl(nfnl_get_data(nfad->data, NFQA_IFINDEX_PHYSINDEV, uint32_t));
1052 return ntohl(nfnl_get_data(nfad->data, NFQA_IFINDEX_OUTDEV, uint32_t));
1068 return ntohl(nfnl_get_data(nfad->data, NFQA_IFINDEX_PHYSOUTDEV, uint32_t));
1114 return nlif_index2name(nlif_handle, ifindex, name);
1134 return nlif_index2name(nlif_handle, ifindex, name);
1154 return nlif_index2name(nlif_handle, ifindex, name);
1175 return nlif_index2name(nlif_handle, ifindex, name);
1203 return nfnl_get_pointer_to_data(nfad->data, NFQA_HWADDR,
1204 struct nfqnl_msg_packet_hw);
1220 if (!nfnl_attr_present(nfad->data, NFQA_UID))
1223 *uid = ntohl(nfnl_get_data(nfad->data, NFQA_UID, uint32_t));
1240 if (!nfnl_attr_present(nfad->data, NFQA_GID))
1243 *gid = ntohl(nfnl_get_data(nfad->data, NFQA_GID, uint32_t));
1261 if (!nfnl_attr_present(nfad->data, NFQA_SECCTX))
1264 *secdata = (
unsigned char *)nfnl_get_pointer_to_data(nfad->data,
1268 return NFA_PAYLOAD(nfad->data[NFQA_SECCTX-1]);
1287 *data = (
unsigned char *)
1288 nfnl_get_pointer_to_data(nfad->data, NFQA_PAYLOAD,
char);
1290 return NFA_PAYLOAD(nfad->data[NFQA_PAYLOAD-1]);
1300 #define SNPRINTF_FAILURE(ret, rem, offset, len) \
1341 struct nfqnl_msg_packet_hdr *ph;
1342 struct nfqnl_msg_packet_hw *hwph;
1345 int size, offset = 0, len = 0, ret;
1346 unsigned char *data;
1348 size = snprintf(buf + offset, rem,
"<pkt>");
1349 SNPRINTF_FAILURE(size, rem, offset, len);
1351 if (flags & NFQ_XML_TIME) {
1356 if (localtime_r(&t, &tm) == NULL)
1359 size = snprintf(buf + offset, rem,
"<when>");
1360 SNPRINTF_FAILURE(size, rem, offset, len);
1362 size = snprintf(buf + offset, rem,
1363 "<hour>%d</hour>", tm.tm_hour);
1364 SNPRINTF_FAILURE(size, rem, offset, len);
1366 size = snprintf(buf + offset,
1367 rem,
"<min>%02d</min>", tm.tm_min);
1368 SNPRINTF_FAILURE(size, rem, offset, len);
1370 size = snprintf(buf + offset,
1371 rem,
"<sec>%02d</sec>", tm.tm_sec);
1372 SNPRINTF_FAILURE(size, rem, offset, len);
1374 size = snprintf(buf + offset, rem,
"<wday>%d</wday>",
1376 SNPRINTF_FAILURE(size, rem, offset, len);
1378 size = snprintf(buf + offset, rem,
"<day>%d</day>", tm.tm_mday);
1379 SNPRINTF_FAILURE(size, rem, offset, len);
1381 size = snprintf(buf + offset, rem,
"<month>%d</month>",
1383 SNPRINTF_FAILURE(size, rem, offset, len);
1385 size = snprintf(buf + offset, rem,
"<year>%d</year>",
1387 SNPRINTF_FAILURE(size, rem, offset, len);
1389 size = snprintf(buf + offset, rem,
"</when>");
1390 SNPRINTF_FAILURE(size, rem, offset, len);
1395 size = snprintf(buf + offset, rem,
1396 "<hook>%u</hook><id>%u</id>",
1397 ph->hook, ntohl(ph->packet_id));
1398 SNPRINTF_FAILURE(size, rem, offset, len);
1401 if (hwph && (flags & NFQ_XML_HW)) {
1402 int i, hlen = ntohs(hwph->hw_addrlen);
1404 size = snprintf(buf + offset, rem,
"<hw><proto>%04x"
1406 ntohs(ph->hw_protocol));
1407 SNPRINTF_FAILURE(size, rem, offset, len);
1409 size = snprintf(buf + offset, rem,
"<src>");
1410 SNPRINTF_FAILURE(size, rem, offset, len);
1412 for (i=0; i<hlen; i++) {
1413 size = snprintf(buf + offset, rem,
"%02x",
1415 SNPRINTF_FAILURE(size, rem, offset, len);
1418 size = snprintf(buf + offset, rem,
"</src></hw>");
1419 SNPRINTF_FAILURE(size, rem, offset, len);
1420 }
else if (flags & NFQ_XML_HW) {
1421 size = snprintf(buf + offset, rem,
"<hw><proto>%04x"
1423 ntohs(ph->hw_protocol));
1424 SNPRINTF_FAILURE(size, rem, offset, len);
1429 if (mark && (flags & NFQ_XML_MARK)) {
1430 size = snprintf(buf + offset, rem,
"<mark>%u</mark>", mark);
1431 SNPRINTF_FAILURE(size, rem, offset, len);
1435 if (ifi && (flags & NFQ_XML_DEV)) {
1436 size = snprintf(buf + offset, rem,
"<indev>%u</indev>", ifi);
1437 SNPRINTF_FAILURE(size, rem, offset, len);
1441 if (ifi && (flags & NFQ_XML_DEV)) {
1442 size = snprintf(buf + offset, rem,
"<outdev>%u</outdev>", ifi);
1443 SNPRINTF_FAILURE(size, rem, offset, len);
1447 if (ifi && (flags & NFQ_XML_PHYSDEV)) {
1448 size = snprintf(buf + offset, rem,
1449 "<physindev>%u</physindev>", ifi);
1450 SNPRINTF_FAILURE(size, rem, offset, len);
1454 if (ifi && (flags & NFQ_XML_PHYSDEV)) {
1455 size = snprintf(buf + offset, rem,
1456 "<physoutdev>%u</physoutdev>", ifi);
1457 SNPRINTF_FAILURE(size, rem, offset, len);
1460 if (
nfq_get_uid(tb, &uid) && (flags & NFQ_XML_UID)) {
1461 size = snprintf(buf + offset, rem,
"<uid>%u</uid>", uid);
1462 SNPRINTF_FAILURE(size, rem, offset, len);
1465 if (
nfq_get_gid(tb, &gid) && (flags & NFQ_XML_GID)) {
1466 size = snprintf(buf + offset, rem,
"<gid>%u</gid>", gid);
1467 SNPRINTF_FAILURE(size, rem, offset, len);
1471 if (ret >= 0 && (flags & NFQ_XML_PAYLOAD)) {
1474 size = snprintf(buf + offset, rem,
"<payload>");
1475 SNPRINTF_FAILURE(size, rem, offset, len);
1477 for (i=0; i<ret; i++) {
1478 size = snprintf(buf + offset, rem,
"%02x",
1480 SNPRINTF_FAILURE(size, rem, offset, len);
1483 size = snprintf(buf + offset, rem,
"</payload>");
1484 SNPRINTF_FAILURE(size, rem, offset, len);
1487 size = snprintf(buf + offset, rem,
"</pkt>");
1488 SNPRINTF_FAILURE(size, rem, offset, len);
struct nfqnl_msg_packet_hw * nfq_get_packet_hw(struct nfq_data *nfad)
int nfq_bind_pf(struct nfq_handle *h, uint16_t pf)
int nfq_set_verdict_batch(struct nfq_q_handle *qh, uint32_t id, uint32_t verdict)
int nfq_get_outdev_name(struct nlif_handle *nlif_handle, struct nfq_data *nfad, char *name)
uint32_t nfq_get_indev(struct nfq_data *nfad)
int nfq_fd(struct nfq_handle *h)
struct nfq_q_handle * nfq_create_queue(struct nfq_handle *h, uint16_t num, nfq_callback *cb, void *data)
int nfq_set_queue_maxlen(struct nfq_q_handle *qh, uint32_t queuelen)
int nfq_snprintf_xml(char *buf, size_t rem, struct nfq_data *tb, int flags)
int nfq_set_verdict_batch2(struct nfq_q_handle *qh, uint32_t id, uint32_t verdict, uint32_t mark)
struct nfqnl_msg_packet_hdr * nfq_get_msg_packet_hdr(struct nfq_data *nfad)
int nfq_get_payload(struct nfq_data *nfad, unsigned char **data)
int nfq_get_physoutdev_name(struct nlif_handle *nlif_handle, struct nfq_data *nfad, char *name)
uint32_t nfq_get_physoutdev(struct nfq_data *nfad)
struct nfq_handle * nfq_open(void)
int nfq_set_mode(struct nfq_q_handle *qh, uint8_t mode, uint32_t range)
int nfq_get_timestamp(struct nfq_data *nfad, struct timeval *tv)
uint32_t nfq_get_physindev(struct nfq_data *nfad)
int nfq_get_gid(struct nfq_data *nfad, uint32_t *gid)
int nfq_destroy_queue(struct nfq_q_handle *qh)
uint32_t nfq_get_nfmark(struct nfq_data *nfad)
int nfq_unbind_pf(struct nfq_handle *h, uint16_t pf)
int nfq_set_verdict_mark(struct nfq_q_handle *qh, uint32_t id, uint32_t verdict, uint32_t mark, uint32_t data_len, const unsigned char *buf)
int nfq_handle_packet(struct nfq_handle *h, char *buf, int len)
int nfq_get_secctx(struct nfq_data *nfad, unsigned char **secdata)
int nfq_close(struct nfq_handle *h)
int nfq_get_indev_name(struct nlif_handle *nlif_handle, struct nfq_data *nfad, char *name)
int nfq_get_uid(struct nfq_data *nfad, uint32_t *uid)
int nfq_get_physindev_name(struct nlif_handle *nlif_handle, struct nfq_data *nfad, char *name)
int nfq_set_queue_flags(struct nfq_q_handle *qh, uint32_t mask, uint32_t flags)
uint32_t nfq_get_outdev(struct nfq_data *nfad)
int nfq_set_verdict2(struct nfq_q_handle *qh, uint32_t id, uint32_t verdict, uint32_t mark, uint32_t data_len, const unsigned char *buf)
int nfq_set_verdict(struct nfq_q_handle *qh, uint32_t id, uint32_t verdict, uint32_t data_len, const unsigned char *buf)