30 #include <netinet/in.h> 31 #include <sys/socket.h> 33 #include <libnfnetlink/libnfnetlink.h> 34 #include <libnetfilter_queue/libnetfilter_queue.h> 128 struct nfnl_handle *nfnlh;
129 struct nfnl_subsys_handle *nfnlssh;
130 struct nfq_q_handle *qh_list;
135 struct nfq_q_handle *next;
136 struct nfq_handle *h;
144 struct nfattr **data;
147 EXPORT_SYMBOL
int nfq_errno;
153 static void del_qh(
struct nfq_q_handle *qh)
155 struct nfq_q_handle *cur_qh, *prev_qh = NULL;
157 for (cur_qh = qh->h->qh_list; cur_qh; cur_qh = cur_qh->next) {
160 prev_qh->next = qh->next;
162 qh->h->qh_list = qh->next;
169 static void add_qh(
struct nfq_q_handle *qh)
171 qh->next = qh->h->qh_list;
175 static struct nfq_q_handle *find_qh(
struct nfq_handle *h, uint16_t
id)
177 struct nfq_q_handle *qh;
179 for (qh = h->qh_list; qh; qh = qh->next) {
188 __build_send_cfg_msg(
struct nfq_handle *h, uint8_t command,
189 uint16_t queuenum, uint16_t pf)
192 char buf[NFNL_HEADER_LEN
193 +NFA_LENGTH(
sizeof(
struct nfqnl_msg_config_cmd))];
196 struct nfqnl_msg_config_cmd cmd;
198 nfnl_fill_hdr(h->nfnlssh, &u.nmh, 0, AF_UNSPEC, queuenum,
199 NFQNL_MSG_CONFIG, NLM_F_REQUEST|NLM_F_ACK);
202 cmd.command = command;
204 nfnl_addattr_l(&u.nmh,
sizeof(u), NFQA_CFG_CMD, &cmd,
sizeof(cmd));
206 return nfnl_query(h->nfnlh, &u.nmh);
209 static int __nfq_rcv_pkt(
struct nlmsghdr *nlh,
struct nfattr *nfa[],
212 struct nfgenmsg *nfmsg = NLMSG_DATA(nlh);
213 struct nfq_handle *h = data;
214 uint16_t queue_num = ntohs(nfmsg->res_id);
215 struct nfq_q_handle *qh = find_qh(h, queue_num);
216 struct nfq_data nfqa;
226 return qh->cb(qh, nfmsg, &nfqa, qh->data);
232 struct nfnl_handle *nfq_nfnlh(
struct nfq_handle *h)
310 return nfnl_fd(nfq_nfnlh(h));
365 struct nfnl_handle *nfnlh = nfnl_open();
366 struct nfq_handle *qh;
372 nfnl_unset_sequence_tracking(nfnlh);
374 qh = nfq_open_nfnl(nfnlh);
396 struct nfq_handle *nfq_open_nfnl(
struct nfnl_handle *nfnlh)
398 struct nfnl_callback pkt_cb = {
399 .call = __nfq_rcv_pkt,
400 .attr_count = NFQA_MAX,
402 struct nfq_handle *h;
405 h = malloc(
sizeof(*h));
409 memset(h, 0,
sizeof(*h));
412 h->nfnlssh = nfnl_subsys_open(h->nfnlh, NFNL_SUBSYS_QUEUE,
420 err = nfnl_callback_register(h->nfnlssh, NFQNL_MSG_PACKET, &pkt_cb);
428 nfnl_subsys_close(h->nfnlssh);
456 ret = nfnl_close(h->nfnlh);
476 return __build_send_cfg_msg(h, NFQNL_CFG_CMD_PF_BIND, 0, pf);
492 return __build_send_cfg_msg(h, NFQNL_CFG_CMD_PF_UNBIND, 0, pf);
539 nfq_callback *cb,
void *data)
542 struct nfq_q_handle *qh;
547 qh = malloc(
sizeof(*qh));
551 memset(qh, 0,
sizeof(*qh));
557 ret = __build_send_cfg_msg(h, NFQNL_CFG_CMD_BIND, num, 0);
587 int ret = __build_send_cfg_msg(qh->h, NFQNL_CFG_CMD_UNBIND, qh->id, 0);
611 return nfnl_handle_packet(h->nfnlh, buf, len);
630 int nfq_set_mode(
struct nfq_q_handle *qh, uint8_t mode, uint32_t range)
633 char buf[NFNL_HEADER_LEN
634 +NFA_LENGTH(
sizeof(
struct nfqnl_msg_config_params))];
637 struct nfqnl_msg_config_params params;
639 nfnl_fill_hdr(qh->h->nfnlssh, &u.nmh, 0, AF_UNSPEC, qh->id,
640 NFQNL_MSG_CONFIG, NLM_F_REQUEST|NLM_F_ACK);
642 params.copy_range = htonl(range);
643 params.copy_mode = mode;
644 nfnl_addattr_l(&u.nmh,
sizeof(u), NFQA_CFG_PARAMS, ¶ms,
647 return nfnl_query(qh->h->nfnlh, &u.nmh);
722 char buf[NFNL_HEADER_LEN
723 +NFA_LENGTH(
sizeof(mask)
724 +NFA_LENGTH(
sizeof(flags)))];
729 flags = htonl(flags);
731 nfnl_fill_hdr(qh->h->nfnlssh, &u.nmh, 0, AF_UNSPEC, qh->id,
732 NFQNL_MSG_CONFIG, NLM_F_REQUEST|NLM_F_ACK);
734 nfnl_addattr32(&u.nmh,
sizeof(u), NFQA_CFG_FLAGS, flags);
735 nfnl_addattr32(&u.nmh,
sizeof(u), NFQA_CFG_MASK, mask);
737 return nfnl_query(qh->h->nfnlh, &u.nmh);
755 char buf[NFNL_HEADER_LEN
756 +NFA_LENGTH(
sizeof(
struct nfqnl_msg_config_params))];
759 uint32_t queue_maxlen = htonl(queuelen);
761 nfnl_fill_hdr(qh->h->nfnlssh, &u.nmh, 0, AF_UNSPEC, qh->id,
762 NFQNL_MSG_CONFIG, NLM_F_REQUEST|NLM_F_ACK);
764 nfnl_addattr_l(&u.nmh,
sizeof(u), NFQA_CFG_QUEUE_MAXLEN, &queue_maxlen,
765 sizeof(queue_maxlen));
767 return nfnl_query(qh->h->nfnlh, &u.nmh);
774 static int __set_verdict(
struct nfq_q_handle *qh, uint32_t
id,
775 uint32_t verdict, uint32_t mark,
int set_mark,
776 uint32_t data_len,
const unsigned char *data,
777 enum nfqnl_msg_types type)
779 struct nfqnl_msg_verdict_hdr vh;
781 char buf[NFNL_HEADER_LEN
782 +NFA_LENGTH(
sizeof(mark))
783 +NFA_LENGTH(
sizeof(vh))];
792 struct nfattr data_attr;
794 memset(iov, 0,
sizeof(iov));
796 vh.verdict = htonl(verdict);
799 nfnl_fill_hdr(qh->h->nfnlssh, &u.nmh, 0, AF_UNSPEC, qh->id,
800 type, NLM_F_REQUEST);
803 nfnl_addattr_l(&u.nmh,
sizeof(u), NFQA_VERDICT_HDR, &vh,
sizeof(vh));
806 nfnl_addattr32(&u.nmh,
sizeof(u), NFQA_MARK, mark);
808 iov[0].iov_base = &u.nmh;
809 iov[0].iov_len = NLMSG_TAIL(&u.nmh) - (
void *)&u.nmh;
814 nfnl_build_nfa_iovec(&iov[1], &data_attr, NFQA_PAYLOAD,
815 data_len, (
unsigned char *) data);
821 u.nmh.nlmsg_len += data_attr.nfa_len;
824 return nfnl_sendiov(qh->h->nfnlh, iov, nvecs, 0);
857 uint32_t verdict, uint32_t data_len,
858 const unsigned char *buf)
860 return __set_verdict(qh,
id, verdict, 0, 0, data_len, buf,
875 uint32_t verdict, uint32_t mark,
876 uint32_t data_len,
const unsigned char *buf)
878 return __set_verdict(qh,
id, verdict, htonl(mark), 1, data_len,
879 buf, NFQNL_MSG_VERDICT);
898 return __set_verdict(qh,
id, verdict, 0, 0, 0, NULL,
899 NFQNL_MSG_VERDICT_BATCH);
911 uint32_t verdict, uint32_t mark)
913 return __set_verdict(qh,
id, verdict, htonl(mark), 1, 0,
914 NULL, NFQNL_MSG_VERDICT_BATCH);
933 uint32_t verdict, uint32_t mark,
934 uint32_t data_len,
const unsigned char *buf)
936 return __set_verdict(qh,
id, verdict, mark, 1, data_len, buf,
976 return nfnl_get_pointer_to_data(nfad->data, NFQA_PACKET_HDR,
977 struct nfqnl_msg_packet_hdr);
989 return ntohl(nfnl_get_data(nfad->data, NFQA_MARK, uint32_t));
1004 struct nfqnl_msg_packet_timestamp *qpt;
1005 qpt = nfnl_get_pointer_to_data(nfad->data, NFQA_TIMESTAMP,
1006 struct nfqnl_msg_packet_timestamp);
1010 tv->tv_sec = __be64_to_cpu(qpt->sec);
1011 tv->tv_usec = __be64_to_cpu(qpt->usec);
1030 return ntohl(nfnl_get_data(nfad->data, NFQA_IFINDEX_INDEV, uint32_t));
1044 return ntohl(nfnl_get_data(nfad->data, NFQA_IFINDEX_PHYSINDEV, uint32_t));
1058 return ntohl(nfnl_get_data(nfad->data, NFQA_IFINDEX_OUTDEV, uint32_t));
1074 return ntohl(nfnl_get_data(nfad->data, NFQA_IFINDEX_PHYSOUTDEV, uint32_t));
1117 struct nfq_data *nfad,
char *name)
1120 return nlif_index2name(nlif_handle, ifindex, name);
1137 struct nfq_data *nfad,
char *name)
1140 return nlif_index2name(nlif_handle, ifindex, name);
1157 struct nfq_data *nfad,
char *name)
1160 return nlif_index2name(nlif_handle, ifindex, name);
1178 struct nfq_data *nfad,
char *name)
1181 return nlif_index2name(nlif_handle, ifindex, name);
1209 return nfnl_get_pointer_to_data(nfad->data, NFQA_HWADDR,
1210 struct nfqnl_msg_packet_hw);
1238 if (!nfnl_attr_present(nfad->data, NFQA_SKB_INFO))
1241 return ntohl(nfnl_get_data(nfad->data, NFQA_SKB_INFO, uint32_t));
1258 if (!nfnl_attr_present(nfad->data, NFQA_UID))
1261 *uid = ntohl(nfnl_get_data(nfad->data, NFQA_UID, uint32_t));
1279 if (!nfnl_attr_present(nfad->data, NFQA_GID))
1282 *gid = ntohl(nfnl_get_data(nfad->data, NFQA_GID, uint32_t));
1300 if (!nfnl_attr_present(nfad->data, NFQA_SECCTX))
1303 *secdata = (
unsigned char *)nfnl_get_pointer_to_data(nfad->data,
1307 return NFA_PAYLOAD(nfad->data[NFQA_SECCTX-1]);
1326 *data = (
unsigned char *)
1327 nfnl_get_pointer_to_data(nfad->data, NFQA_PAYLOAD,
char);
1329 return NFA_PAYLOAD(nfad->data[NFQA_PAYLOAD-1]);
1338 #define SNPRINTF_FAILURE(ret, rem, offset, len) \ 1380 struct nfqnl_msg_packet_hdr *ph;
1381 struct nfqnl_msg_packet_hw *hwph;
1384 int size, offset = 0, len = 0, ret;
1385 unsigned char *data;
1387 size = snprintf(buf + offset, rem,
"<pkt>");
1388 SNPRINTF_FAILURE(size, rem, offset, len);
1390 if (flags & NFQ_XML_TIME) {
1395 if (localtime_r(&t, &tm) == NULL)
1398 size = snprintf(buf + offset, rem,
"<when>");
1399 SNPRINTF_FAILURE(size, rem, offset, len);
1401 size = snprintf(buf + offset, rem,
1402 "<hour>%d</hour>", tm.tm_hour);
1403 SNPRINTF_FAILURE(size, rem, offset, len);
1405 size = snprintf(buf + offset,
1406 rem,
"<min>%02d</min>", tm.tm_min);
1407 SNPRINTF_FAILURE(size, rem, offset, len);
1409 size = snprintf(buf + offset,
1410 rem,
"<sec>%02d</sec>", tm.tm_sec);
1411 SNPRINTF_FAILURE(size, rem, offset, len);
1413 size = snprintf(buf + offset, rem,
"<wday>%d</wday>",
1415 SNPRINTF_FAILURE(size, rem, offset, len);
1417 size = snprintf(buf + offset, rem,
"<day>%d</day>", tm.tm_mday);
1418 SNPRINTF_FAILURE(size, rem, offset, len);
1420 size = snprintf(buf + offset, rem,
"<month>%d</month>",
1422 SNPRINTF_FAILURE(size, rem, offset, len);
1424 size = snprintf(buf + offset, rem,
"<year>%d</year>",
1426 SNPRINTF_FAILURE(size, rem, offset, len);
1428 size = snprintf(buf + offset, rem,
"</when>");
1429 SNPRINTF_FAILURE(size, rem, offset, len);
1434 size = snprintf(buf + offset, rem,
1435 "<hook>%u</hook><id>%u</id>",
1436 ph->hook, ntohl(ph->packet_id));
1437 SNPRINTF_FAILURE(size, rem, offset, len);
1440 if (hwph && (flags & NFQ_XML_HW)) {
1441 int i, hlen = ntohs(hwph->hw_addrlen);
1443 size = snprintf(buf + offset, rem,
"<hw><proto>%04x" 1445 ntohs(ph->hw_protocol));
1446 SNPRINTF_FAILURE(size, rem, offset, len);
1448 size = snprintf(buf + offset, rem,
"<src>");
1449 SNPRINTF_FAILURE(size, rem, offset, len);
1451 for (i=0; i<hlen; i++) {
1452 size = snprintf(buf + offset, rem,
"%02x",
1454 SNPRINTF_FAILURE(size, rem, offset, len);
1457 size = snprintf(buf + offset, rem,
"</src></hw>");
1458 SNPRINTF_FAILURE(size, rem, offset, len);
1459 }
else if (flags & NFQ_XML_HW) {
1460 size = snprintf(buf + offset, rem,
"<hw><proto>%04x" 1462 ntohs(ph->hw_protocol));
1463 SNPRINTF_FAILURE(size, rem, offset, len);
1468 if (mark && (flags & NFQ_XML_MARK)) {
1469 size = snprintf(buf + offset, rem,
"<mark>%u</mark>", mark);
1470 SNPRINTF_FAILURE(size, rem, offset, len);
1474 if (ifi && (flags & NFQ_XML_DEV)) {
1475 size = snprintf(buf + offset, rem,
"<indev>%u</indev>", ifi);
1476 SNPRINTF_FAILURE(size, rem, offset, len);
1480 if (ifi && (flags & NFQ_XML_DEV)) {
1481 size = snprintf(buf + offset, rem,
"<outdev>%u</outdev>", ifi);
1482 SNPRINTF_FAILURE(size, rem, offset, len);
1486 if (ifi && (flags & NFQ_XML_PHYSDEV)) {
1487 size = snprintf(buf + offset, rem,
1488 "<physindev>%u</physindev>", ifi);
1489 SNPRINTF_FAILURE(size, rem, offset, len);
1493 if (ifi && (flags & NFQ_XML_PHYSDEV)) {
1494 size = snprintf(buf + offset, rem,
1495 "<physoutdev>%u</physoutdev>", ifi);
1496 SNPRINTF_FAILURE(size, rem, offset, len);
1499 if (
nfq_get_uid(tb, &uid) && (flags & NFQ_XML_UID)) {
1500 size = snprintf(buf + offset, rem,
"<uid>%u</uid>", uid);
1501 SNPRINTF_FAILURE(size, rem, offset, len);
1504 if (
nfq_get_gid(tb, &gid) && (flags & NFQ_XML_GID)) {
1505 size = snprintf(buf + offset, rem,
"<gid>%u</gid>", gid);
1506 SNPRINTF_FAILURE(size, rem, offset, len);
1510 if (ret >= 0 && (flags & NFQ_XML_PAYLOAD)) {
1513 size = snprintf(buf + offset, rem,
"<payload>");
1514 SNPRINTF_FAILURE(size, rem, offset, len);
1516 for (i=0; i<ret; i++) {
1517 size = snprintf(buf + offset, rem,
"%02x",
1519 SNPRINTF_FAILURE(size, rem, offset, len);
1522 size = snprintf(buf + offset, rem,
"</payload>");
1523 SNPRINTF_FAILURE(size, rem, offset, len);
1526 size = snprintf(buf + offset, rem,
"</pkt>");
1527 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)
uint32_t nfq_get_skbinfo(struct nfq_data *nfad)
int nfq_set_verdict(struct nfq_q_handle *qh, uint32_t id, uint32_t verdict, uint32_t data_len, const unsigned char *buf)