mirror of
https://github.com/Waujito/youtubeUnblock.git
synced 2025-01-15 19:15:17 +00:00
Add conntrack parse skeleton
This commit is contained in:
parent
8bf2ab9e9b
commit
84d47b8a3d
38
src/config.h
38
src/config.h
@ -284,4 +284,42 @@ struct config_t config = default_config_set; \
|
|||||||
config->last_section = &(config.default_config) \
|
config->last_section = &(config.default_config) \
|
||||||
|
|
||||||
|
|
||||||
|
struct ytb_conntrack {
|
||||||
|
uint32_t mask;
|
||||||
|
|
||||||
|
uint64_t orig_packets;
|
||||||
|
uint64_t repl_packets;
|
||||||
|
uint64_t orig_bytes;
|
||||||
|
uint64_t repl_bytes;
|
||||||
|
uint32_t connmark;
|
||||||
|
uint32_t id;
|
||||||
|
};
|
||||||
|
|
||||||
|
enum yct_attrs {
|
||||||
|
YCTATTR_ORIG_PACKETS,
|
||||||
|
YCTATTR_REPL_PACKETS,
|
||||||
|
YCTATTR_ORIG_BYTES,
|
||||||
|
YCTATTR_REPL_BYTES,
|
||||||
|
YCTATTR_CONNMARK,
|
||||||
|
YCTATTR_CONNID,
|
||||||
|
};
|
||||||
|
/* enum yct_attrs attr, struct ytb_conntrack * yct */
|
||||||
|
#define yct_set_mask_attr(attr, yct) \
|
||||||
|
((yct)->mask |= (1 << (attr)))
|
||||||
|
|
||||||
|
/* enum yct_attrs attr, const struct ytb_conntrack * yct */
|
||||||
|
#define yct_is_mask_attr(attr, yct) \
|
||||||
|
(((yct)->mask & (1 << (attr))) == (1 << (attr)))
|
||||||
|
|
||||||
|
/* enum yct_attrs attr, struct ytb_conntrack * yct */
|
||||||
|
#define yct_del_mask_attr(attr, yct) \
|
||||||
|
(yct)->mask &= ~(1 << (attr))
|
||||||
|
|
||||||
|
|
||||||
|
struct packet_data {
|
||||||
|
const uint8_t *payload;
|
||||||
|
size_t payload_len;
|
||||||
|
struct ytb_conntrack yct;
|
||||||
|
};
|
||||||
|
|
||||||
#endif /* YTB_CONFIG_H */
|
#endif /* YTB_CONFIG_H */
|
||||||
|
@ -251,10 +251,10 @@ struct instance_config_t instance_config = {
|
|||||||
.send_delayed_packet = delay_packet_send,
|
.send_delayed_packet = delay_packet_send,
|
||||||
};
|
};
|
||||||
|
|
||||||
static int connbytes_pkts(const struct sk_buff *skb) {
|
static int conntrack_parse(const struct sk_buff *skb,
|
||||||
|
struct ytb_conntrack *yct) {
|
||||||
const struct nf_conn *ct;
|
const struct nf_conn *ct;
|
||||||
enum ip_conntrack_info ctinfo;
|
enum ip_conntrack_info ctinfo;
|
||||||
u_int64_t pkts = 0;
|
|
||||||
const struct nf_conn_counter *counters;
|
const struct nf_conn_counter *counters;
|
||||||
|
|
||||||
ct = nf_ct_get(skb, &ctinfo);
|
ct = nf_ct_get(skb, &ctinfo);
|
||||||
@ -273,9 +273,20 @@ static int connbytes_pkts(const struct sk_buff *skb) {
|
|||||||
return -1;
|
return -1;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
pkts = atomic64_read(&counters[IP_CT_DIR_ORIGINAL].packets);
|
yct->orig_packets = atomic64_read(&counters[IP_CT_DIR_ORIGINAL].packets);
|
||||||
|
yct_set_mask_attr(YCTATTR_ORIG_PACKETS, yct);
|
||||||
|
yct->orig_bytes = atomic64_read(&counters[IP_CT_DIR_ORIGINAL].bytes);
|
||||||
|
yct_set_mask_attr(YCTATTR_ORIG_BYTES, yct);
|
||||||
|
yct->repl_packets = atomic64_read(&counters[IP_CT_DIR_REPLY].packets);
|
||||||
|
yct_set_mask_attr(YCTATTR_REPL_PACKETS, yct);
|
||||||
|
yct->repl_bytes = atomic64_read(&counters[IP_CT_DIR_REPLY].bytes);
|
||||||
|
yct_set_mask_attr(YCTATTR_REPL_BYTES, yct);
|
||||||
|
yct->connmark = READ_ONCE(ct->mark);
|
||||||
|
yct_set_mask_attr(YCTATTR_CONNMARK, yct);
|
||||||
|
yct->id = nf_ct_get_id(ct);
|
||||||
|
yct_set_mask_attr(YCTATTR_CONNID, yct);
|
||||||
|
|
||||||
return pkts;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If this is a Red Hat-based kernel (Red Hat, CentOS, Fedora, etc)... */
|
/* If this is a Red Hat-based kernel (Red Hat, CentOS, Fedora, etc)... */
|
||||||
@ -346,6 +357,7 @@ static int connbytes_pkts(const struct sk_buff *skb) {
|
|||||||
|
|
||||||
static NF_CALLBACK(ykb_nf_hook, skb) {
|
static NF_CALLBACK(ykb_nf_hook, skb) {
|
||||||
int ret;
|
int ret;
|
||||||
|
struct packet_data pd = {0};
|
||||||
|
|
||||||
if ((skb->mark & config.mark) == config.mark)
|
if ((skb->mark & config.mark) == config.mark)
|
||||||
goto accept;
|
goto accept;
|
||||||
@ -356,16 +368,28 @@ static NF_CALLBACK(ykb_nf_hook, skb) {
|
|||||||
if (skb->len > MAX_PACKET_SIZE)
|
if (skb->len > MAX_PACKET_SIZE)
|
||||||
goto accept;
|
goto accept;
|
||||||
|
|
||||||
if (config.connbytes_limit != 0 && connbytes_pkts(skb) > config.connbytes_limit)
|
ret = conntrack_parse(skb, &pd.yct);
|
||||||
|
if (ret < 0) {
|
||||||
|
lgtrace("[TRACE] conntrack_parse error code\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
lgtrace("[CONNTRACK TRACE] orig_packets=%llu repl_packets=%llu orig_bytes=%llu repl_bytes=%llu connmark=%d id=%ud\n", pd.yct.orig_packets, pd.yct.repl_packets, pd.yct.orig_bytes, pd.yct.repl_bytes, pd.yct.connmark, pd.yct.id);
|
||||||
|
|
||||||
|
if (config.connbytes_limit != 0 && yct_is_mask_attr(YCTATTR_ORIG_PACKETS, &pd.yct) && pd.yct.orig_packets > config.connbytes_limit)
|
||||||
goto accept;
|
goto accept;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
ret = skb_linearize(skb);
|
ret = skb_linearize(skb);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
lgerror(ret, "Cannot linearize");
|
lgerror(ret, "Cannot linearize");
|
||||||
goto accept;
|
goto accept;
|
||||||
}
|
}
|
||||||
|
|
||||||
int vrd = process_packet(skb->data, skb->len);
|
pd.payload = skb->data;
|
||||||
|
pd.payload_len = skb->len;
|
||||||
|
|
||||||
|
int vrd = process_packet(&pd);
|
||||||
|
|
||||||
switch(vrd) {
|
switch(vrd) {
|
||||||
case PKT_ACCEPT:
|
case PKT_ACCEPT:
|
||||||
|
@ -32,7 +32,10 @@
|
|||||||
#include "linux/inet.h"
|
#include "linux/inet.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int process_packet(const uint8_t *raw_payload, size_t raw_payload_len) {
|
int process_packet(const struct packet_data *pd) {
|
||||||
|
const uint8_t *raw_payload = pd->payload;
|
||||||
|
uint32_t raw_payload_len = pd->payload_len;
|
||||||
|
|
||||||
if (raw_payload_len > MAX_PACKET_SIZE) {
|
if (raw_payload_len > MAX_PACKET_SIZE) {
|
||||||
return PKT_ACCEPT;
|
return PKT_ACCEPT;
|
||||||
}
|
}
|
||||||
|
@ -22,6 +22,7 @@
|
|||||||
|
|
||||||
#include "types.h"
|
#include "types.h"
|
||||||
#include "tls.h"
|
#include "tls.h"
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
#define PKT_ACCEPT 0
|
#define PKT_ACCEPT 0
|
||||||
#define PKT_DROP 1
|
#define PKT_DROP 1
|
||||||
@ -32,7 +33,7 @@
|
|||||||
* Processes the packet and returns verdict.
|
* Processes the packet and returns verdict.
|
||||||
* This is the primary function that traverses the packet.
|
* This is the primary function that traverses the packet.
|
||||||
*/
|
*/
|
||||||
int process_packet(const uint8_t *packet, size_t packet_len);
|
int process_packet(const struct packet_data *pd);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -196,6 +196,231 @@ static int close_raw6_socket(void) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* libnetfilter_conntrack
|
||||||
|
* (C) 2005-2012 by Pablo Neira Ayuso <pablo@netfilter.org>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This code has been sponsored by Vyatta Inc. <http://www.vyatta.com>
|
||||||
|
*/
|
||||||
|
|
||||||
|
enum ctattr_counters {
|
||||||
|
CTA_COUNTERS_UNSPEC,
|
||||||
|
CTA_COUNTERS_PACKETS, /* 64bit counters */
|
||||||
|
CTA_COUNTERS_BYTES, /* 64bit counters */
|
||||||
|
CTA_COUNTERS32_PACKETS, /* old 32bit counters, unused */
|
||||||
|
CTA_COUNTERS32_BYTES, /* old 32bit counters, unused */
|
||||||
|
CTA_COUNTERS_PAD,
|
||||||
|
__CTA_COUNTERS_MAX
|
||||||
|
};
|
||||||
|
#define CTA_COUNTERS_MAX (__CTA_COUNTERS_MAX - 1)
|
||||||
|
|
||||||
|
enum ctattr_type {
|
||||||
|
CTA_UNSPEC,
|
||||||
|
CTA_TUPLE_ORIG,
|
||||||
|
CTA_TUPLE_REPLY,
|
||||||
|
CTA_STATUS,
|
||||||
|
CTA_PROTOINFO,
|
||||||
|
CTA_HELP,
|
||||||
|
CTA_NAT_SRC,
|
||||||
|
#define CTA_NAT CTA_NAT_SRC /* backwards compatibility */
|
||||||
|
CTA_TIMEOUT,
|
||||||
|
CTA_MARK,
|
||||||
|
CTA_COUNTERS_ORIG,
|
||||||
|
CTA_COUNTERS_REPLY,
|
||||||
|
CTA_USE,
|
||||||
|
CTA_ID,
|
||||||
|
CTA_NAT_DST,
|
||||||
|
CTA_TUPLE_MASTER,
|
||||||
|
CTA_SEQ_ADJ_ORIG,
|
||||||
|
CTA_NAT_SEQ_ADJ_ORIG = CTA_SEQ_ADJ_ORIG,
|
||||||
|
CTA_SEQ_ADJ_REPLY,
|
||||||
|
CTA_NAT_SEQ_ADJ_REPLY = CTA_SEQ_ADJ_REPLY,
|
||||||
|
CTA_SECMARK, /* obsolete */
|
||||||
|
CTA_ZONE,
|
||||||
|
CTA_SECCTX,
|
||||||
|
CTA_TIMESTAMP,
|
||||||
|
CTA_MARK_MASK,
|
||||||
|
CTA_LABELS,
|
||||||
|
CTA_LABELS_MASK,
|
||||||
|
CTA_SYNPROXY,
|
||||||
|
CTA_FILTER,
|
||||||
|
CTA_STATUS_MASK,
|
||||||
|
__CTA_MAX
|
||||||
|
};
|
||||||
|
#define CTA_MAX (__CTA_MAX - 1)
|
||||||
|
|
||||||
|
enum {
|
||||||
|
__DIR_ORIG,
|
||||||
|
__DIR_REPL
|
||||||
|
};
|
||||||
|
|
||||||
|
static int
|
||||||
|
yct_parse_counters_attr_cb(const struct nlattr *attr, void *data)
|
||||||
|
{
|
||||||
|
const struct nlattr **tb = data;
|
||||||
|
int type = mnl_attr_get_type(attr);
|
||||||
|
|
||||||
|
if (mnl_attr_type_valid(attr, CTA_COUNTERS_MAX) < 0)
|
||||||
|
return MNL_CB_OK;
|
||||||
|
|
||||||
|
switch(type) {
|
||||||
|
case CTA_COUNTERS_PACKETS:
|
||||||
|
case CTA_COUNTERS_BYTES:
|
||||||
|
if (mnl_attr_validate(attr, MNL_TYPE_U64) < 0)
|
||||||
|
return MNL_CB_ERROR;
|
||||||
|
break;
|
||||||
|
case CTA_COUNTERS32_PACKETS:
|
||||||
|
case CTA_COUNTERS32_BYTES:
|
||||||
|
if (mnl_attr_validate(attr, MNL_TYPE_U32) < 0)
|
||||||
|
return MNL_CB_ERROR;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
tb[type] = attr;
|
||||||
|
return MNL_CB_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
yct_parse_counters(const struct nlattr *attr, struct ytb_conntrack *yct,
|
||||||
|
int dir)
|
||||||
|
{
|
||||||
|
struct nlattr *tb[CTA_COUNTERS_MAX+1] = {0};
|
||||||
|
|
||||||
|
if (mnl_attr_parse_nested(attr, yct_parse_counters_attr_cb, tb) < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if (tb[CTA_COUNTERS_PACKETS] || tb[CTA_COUNTERS32_PACKETS]) {
|
||||||
|
uint64_t packets_counter;
|
||||||
|
if (tb[CTA_COUNTERS32_PACKETS]) {
|
||||||
|
packets_counter =
|
||||||
|
ntohl(mnl_attr_get_u32(tb[CTA_COUNTERS32_PACKETS]));
|
||||||
|
}
|
||||||
|
if (tb[CTA_COUNTERS_PACKETS]) {
|
||||||
|
packets_counter =
|
||||||
|
be64toh(mnl_attr_get_u64(tb[CTA_COUNTERS_PACKETS]));
|
||||||
|
}
|
||||||
|
switch(dir) {
|
||||||
|
case __DIR_ORIG:
|
||||||
|
yct->orig_packets = packets_counter;
|
||||||
|
yct_set_mask_attr(YCTATTR_ORIG_PACKETS, yct);
|
||||||
|
break;
|
||||||
|
case __DIR_REPL:
|
||||||
|
yct->repl_packets = packets_counter;
|
||||||
|
yct_set_mask_attr(YCTATTR_REPL_PACKETS, yct);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (tb[CTA_COUNTERS_BYTES] || tb[CTA_COUNTERS32_BYTES]) {
|
||||||
|
uint64_t bytes_counter;
|
||||||
|
if (tb[CTA_COUNTERS32_BYTES]) {
|
||||||
|
bytes_counter =
|
||||||
|
ntohl(mnl_attr_get_u32(tb[CTA_COUNTERS32_BYTES]));
|
||||||
|
}
|
||||||
|
if (tb[CTA_COUNTERS_BYTES]) {
|
||||||
|
bytes_counter =
|
||||||
|
be64toh(mnl_attr_get_u64(tb[CTA_COUNTERS_BYTES]));
|
||||||
|
}
|
||||||
|
|
||||||
|
switch(dir) {
|
||||||
|
case __DIR_ORIG:
|
||||||
|
yct->orig_bytes = bytes_counter;
|
||||||
|
yct_set_mask_attr(YCTATTR_ORIG_BYTES, yct);
|
||||||
|
break;
|
||||||
|
case __DIR_REPL:
|
||||||
|
yct->repl_bytes = bytes_counter;
|
||||||
|
yct_set_mask_attr(YCTATTR_REPL_BYTES, yct);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
yct_parse_conntrack_attr_cb(const struct nlattr *attr, void *data){
|
||||||
|
const struct nlattr **tb = data;
|
||||||
|
int type = mnl_attr_get_type(attr);
|
||||||
|
|
||||||
|
if (mnl_attr_type_valid(attr, CTA_MAX) < 0)
|
||||||
|
return MNL_CB_OK;
|
||||||
|
|
||||||
|
switch(type) {
|
||||||
|
case CTA_TUPLE_ORIG:
|
||||||
|
case CTA_TUPLE_REPLY:
|
||||||
|
case CTA_TUPLE_MASTER:
|
||||||
|
case CTA_NAT_SEQ_ADJ_ORIG:
|
||||||
|
case CTA_NAT_SEQ_ADJ_REPLY:
|
||||||
|
case CTA_PROTOINFO:
|
||||||
|
case CTA_COUNTERS_ORIG:
|
||||||
|
case CTA_COUNTERS_REPLY:
|
||||||
|
case CTA_HELP:
|
||||||
|
case CTA_SECCTX:
|
||||||
|
case CTA_TIMESTAMP:
|
||||||
|
if (mnl_attr_validate(attr, MNL_TYPE_NESTED) < 0)
|
||||||
|
return MNL_CB_ERROR;
|
||||||
|
break;
|
||||||
|
case CTA_STATUS:
|
||||||
|
case CTA_TIMEOUT:
|
||||||
|
case CTA_MARK:
|
||||||
|
case CTA_SECMARK:
|
||||||
|
case CTA_USE:
|
||||||
|
case CTA_ID:
|
||||||
|
if (mnl_attr_validate(attr, MNL_TYPE_U32) < 0)
|
||||||
|
return MNL_CB_ERROR;
|
||||||
|
break;
|
||||||
|
case CTA_ZONE:
|
||||||
|
if (mnl_attr_validate(attr, MNL_TYPE_U16) < 0)
|
||||||
|
return MNL_CB_ERROR;
|
||||||
|
break;
|
||||||
|
case CTA_NAT_SRC:
|
||||||
|
case CTA_NAT_DST:
|
||||||
|
/* deprecated */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
tb[type] = attr;
|
||||||
|
return MNL_CB_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
yct_payload_parse(const void *payload, size_t payload_len,
|
||||||
|
uint16_t l3num, struct ytb_conntrack *yct)
|
||||||
|
{
|
||||||
|
struct nlattr *tb[CTA_MAX+1] = {0};
|
||||||
|
|
||||||
|
if (mnl_attr_parse_payload(payload, payload_len,
|
||||||
|
yct_parse_conntrack_attr_cb, tb) < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if (tb[CTA_MARK]) {
|
||||||
|
yct->connmark = ntohl(mnl_attr_get_u32(tb[CTA_MARK]));
|
||||||
|
yct_set_mask_attr(YCTATTR_CONNMARK, yct);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (tb[CTA_COUNTERS_ORIG]) {
|
||||||
|
if (yct_parse_counters(tb[CTA_COUNTERS_ORIG],
|
||||||
|
yct, __DIR_ORIG) < 0)
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tb[CTA_ID]) {
|
||||||
|
yct->id = ntohl(mnl_attr_get_u32(tb[CTA_ID]));
|
||||||
|
yct_set_mask_attr(YCTATTR_CONNID, yct);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tb[CTA_COUNTERS_REPLY]) {
|
||||||
|
if (yct_parse_counters(tb[CTA_COUNTERS_REPLY],
|
||||||
|
yct, __DIR_REPL) < 0)
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int send_raw_ipv4(const uint8_t *pkt, size_t pktlen) {
|
static int send_raw_ipv4(const uint8_t *pkt, size_t pktlen) {
|
||||||
int ret;
|
int ret;
|
||||||
if (pktlen > AVAILABLE_MTU) return -ENOMEM;
|
if (pktlen > AVAILABLE_MTU) return -ENOMEM;
|
||||||
@ -338,15 +563,6 @@ free_buffs:
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct packet_data {
|
|
||||||
uint32_t id;
|
|
||||||
uint16_t hw_proto;
|
|
||||||
uint8_t hook;
|
|
||||||
|
|
||||||
void *payload;
|
|
||||||
uint16_t payload_len;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Per-queue data. Passed to queue_cb.
|
// Per-queue data. Passed to queue_cb.
|
||||||
struct queue_data {
|
struct queue_data {
|
||||||
struct mnl_socket **_nl;
|
struct mnl_socket **_nl;
|
||||||
@ -418,6 +634,12 @@ static int queue_cb(const struct nlmsghdr *nlh, void *data) {
|
|||||||
struct nfqnl_msg_packet_hdr *ph = NULL;
|
struct nfqnl_msg_packet_hdr *ph = NULL;
|
||||||
struct nlattr *attr[NFQA_MAX+1] = {0};
|
struct nlattr *attr[NFQA_MAX+1] = {0};
|
||||||
struct packet_data packet = {0};
|
struct packet_data packet = {0};
|
||||||
|
struct ytb_conntrack *yct = &packet.yct;
|
||||||
|
struct nfgenmsg *nfg;
|
||||||
|
struct nlmsghdr *verdnlh;
|
||||||
|
int ret;
|
||||||
|
uint16_t l3num;
|
||||||
|
uint32_t id;
|
||||||
|
|
||||||
if (nfq_nlmsg_parse(nlh, attr) < 0) {
|
if (nfq_nlmsg_parse(nlh, attr) < 0) {
|
||||||
lgerror(-errno, "Attr parse");
|
lgerror(-errno, "Attr parse");
|
||||||
@ -430,39 +652,55 @@ static int queue_cb(const struct nlmsghdr *nlh, void *data) {
|
|||||||
return MNL_CB_ERROR;
|
return MNL_CB_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
nfg = mnl_nlmsg_get_payload(nlh);
|
||||||
|
l3num = nfg->nfgen_family;
|
||||||
|
|
||||||
ph = mnl_attr_get_payload(attr[NFQA_PACKET_HDR]);
|
ph = mnl_attr_get_payload(attr[NFQA_PACKET_HDR]);
|
||||||
|
|
||||||
packet.id = ntohl(ph->packet_id);
|
id = ntohl(ph->packet_id);
|
||||||
packet.hw_proto = ntohs(ph->hw_protocol);
|
|
||||||
packet.hook = ph->hook;
|
|
||||||
packet.payload_len = mnl_attr_get_payload_len(attr[NFQA_PAYLOAD]);
|
packet.payload_len = mnl_attr_get_payload_len(attr[NFQA_PAYLOAD]);
|
||||||
packet.payload = mnl_attr_get_payload(attr[NFQA_PAYLOAD]);
|
packet.payload = mnl_attr_get_payload(attr[NFQA_PAYLOAD]);
|
||||||
|
|
||||||
if (attr[NFQA_CAP_LEN] != NULL && ntohl(mnl_attr_get_u32(attr[NFQA_CAP_LEN])) != packet.payload_len) {
|
if (attr[NFQA_CAP_LEN] != NULL && ntohl(mnl_attr_get_u32(attr[NFQA_CAP_LEN])) != packet.payload_len) {
|
||||||
lgerr("The packet was truncated! Skip!");
|
lgerr("The packet was truncated! Skip!");
|
||||||
return fallback_accept_packet(packet.id, *qdata);
|
return fallback_accept_packet(id, *qdata);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (attr[NFQA_MARK] != NULL) {
|
if (attr[NFQA_MARK] != NULL) {
|
||||||
// Skip packets sent by rawsocket to escape infinity loop.
|
// Skip packets sent by rawsocket to escape infinity loop.
|
||||||
if ((ntohl(mnl_attr_get_u32(attr[NFQA_MARK])) & config.mark) ==
|
if ((ntohl(mnl_attr_get_u32(attr[NFQA_MARK])) & config.mark) ==
|
||||||
config.mark) {
|
config.mark) {
|
||||||
return fallback_accept_packet(packet.id, *qdata);
|
return fallback_accept_packet(id, *qdata);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (attr[NFQA_CT] != NULL) {
|
||||||
|
ret = yct_payload_parse(
|
||||||
|
mnl_attr_get_payload(attr[NFQA_CT]),
|
||||||
|
mnl_attr_get_payload_len(attr[NFQA_CT]),
|
||||||
|
l3num, yct);
|
||||||
|
if (ret < 0) {
|
||||||
|
lgerror(ret, "Cannot parse CT");
|
||||||
|
|
||||||
struct nlmsghdr *verdnlh;
|
goto ct_out;
|
||||||
|
}
|
||||||
|
|
||||||
|
lgtrace("[CONNTRACK TRACE] orig_packets=%lu repl_packets=%lu orig_bytes=%lu repl_bytes=%lu connmark=%d id=%ud\n", yct->orig_packets, yct->repl_packets, yct->orig_bytes, yct->repl_bytes, yct->connmark, yct->id);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
ct_out:
|
||||||
verdnlh = nfq_nlmsg_put(buf, NFQNL_MSG_VERDICT, qdata->queue_num);
|
verdnlh = nfq_nlmsg_put(buf, NFQNL_MSG_VERDICT, qdata->queue_num);
|
||||||
|
|
||||||
int ret = process_packet(packet.payload, packet.payload_len);
|
ret = process_packet(&packet);
|
||||||
|
|
||||||
switch (ret) {
|
switch (ret) {
|
||||||
case PKT_DROP:
|
case PKT_DROP:
|
||||||
nfq_nlmsg_verdict_put(verdnlh, packet.id, NF_DROP);
|
nfq_nlmsg_verdict_put(verdnlh, id, NF_DROP);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
nfq_nlmsg_verdict_put(verdnlh, packet.id, NF_ACCEPT);
|
nfq_nlmsg_verdict_put(verdnlh, id, NF_ACCEPT);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -544,10 +782,18 @@ int init_queue(int queue_num) {
|
|||||||
nlh = nfq_nlmsg_put(buf, NFQNL_MSG_CONFIG, queue_num);
|
nlh = nfq_nlmsg_put(buf, NFQNL_MSG_CONFIG, queue_num);
|
||||||
nfq_nlmsg_cfg_put_params(nlh, NFQNL_COPY_PACKET, 0xffff);
|
nfq_nlmsg_cfg_put_params(nlh, NFQNL_COPY_PACKET, 0xffff);
|
||||||
|
|
||||||
|
unsigned int cfg_flags = NFQA_CFG_F_GSO | NFQA_CFG_F_CONNTRACK | NFQA_CFG_F_FAIL_OPEN;
|
||||||
|
unsigned int cfg_mask = 0;
|
||||||
|
|
||||||
if (config.use_gso) {
|
if (config.use_gso) {
|
||||||
mnl_attr_put_u32(nlh, NFQA_CFG_FLAGS, htonl(NFQA_CFG_F_GSO));
|
cfg_mask |= NFQA_CFG_F_GSO;
|
||||||
mnl_attr_put_u32(nlh, NFQA_CFG_MASK, htonl(NFQA_CFG_F_GSO));
|
|
||||||
}
|
}
|
||||||
|
cfg_mask |= NFQA_CFG_F_CONNTRACK;
|
||||||
|
cfg_mask |= NFQA_CFG_F_FAIL_OPEN;
|
||||||
|
|
||||||
|
mnl_attr_put_u32(nlh, NFQA_CFG_FLAGS, htonl(cfg_flags));
|
||||||
|
mnl_attr_put_u32(nlh, NFQA_CFG_MASK, htonl(cfg_mask));
|
||||||
|
|
||||||
|
|
||||||
if (mnl_socket_sendto(nl, nlh, nlh->nlmsg_len) < 0) {
|
if (mnl_socket_sendto(nl, nlh, nlh->nlmsg_len) < 0) {
|
||||||
lgerror(-errno, "mnl_socket_send");
|
lgerror(-errno, "mnl_socket_send");
|
||||||
|
Loading…
Reference in New Issue
Block a user