tpws: comma separated values in --filter-tcp

This commit is contained in:
bol-van 2024-10-29 17:17:58 +03:00
parent 2464d27550
commit acfd844a49
7 changed files with 80 additions and 14 deletions

View File

@ -268,6 +268,11 @@ bool pf_parse(const char *s, port_filter *pf)
char c;
if (!s) return false;
if (*s=='*' && s[1]==0)
{
pf->from=1; pf->to=0xFFFF;
return true;
}
if (*s=='~')
{
pf->neg=true;

View File

@ -149,6 +149,7 @@ struct desync_profile_list *dp_list_add(struct desync_profile_list_head *head)
LIST_INIT(&entry->dp.hl_collection_exclude);
LIST_INIT(&entry->dp.ips_collection);
LIST_INIT(&entry->dp.ips_collection_exclude);
LIST_INIT(&entry->dp.pf_tcp);
entry->dp.filter_ipv4 = entry->dp.filter_ipv6 = true;
memcpy(entry->dp.hostspell, "host", 4); // default hostspell
@ -173,6 +174,7 @@ static void dp_entry_destroy(struct desync_profile_list *entry)
hostlist_collection_destroy(&entry->dp.hl_collection_exclude);
ipset_collection_destroy(&entry->dp.ips_collection);
ipset_collection_destroy(&entry->dp.ips_collection_exclude);
port_filters_destroy(&entry->dp.pf_tcp);
HostFailPoolDestroy(&entry->dp.hostlist_auto_fail_counters);
free(entry);
}

View File

@ -50,7 +50,7 @@ struct desync_profile
unsigned int tamper_start,tamper_cutoff;
bool filter_ipv4,filter_ipv6;
port_filter pf_tcp;
struct port_filters_head pf_tcp;
uint32_t filter_l7; // L7_PROTO_* bits
// list of pointers to ipsets

View File

@ -448,3 +448,36 @@ bool ipset_collection_is_empty(const struct ipset_collection_head *head)
}
return true;
}
bool port_filter_add(struct port_filters_head *head, const port_filter *pf)
{
struct port_filter_item *entry = malloc(sizeof(struct port_filter_item));
if (entry)
{
entry->pf = *pf;
LIST_INSERT_HEAD(head, entry, next);
}
return entry;
}
void port_filters_destroy(struct port_filters_head *head)
{
struct port_filter_item *entry;
while ((entry = LIST_FIRST(head)))
{
LIST_REMOVE(entry, next);
free(entry);
}
}
bool port_filters_in_range(const struct port_filters_head *head, uint16_t port)
{
const struct port_filter_item *item;
if (!LIST_FIRST(head)) return true;
LIST_FOREACH(item, head, next)
{
if (pf_in_range(port, &item->pf))
return true;
}
return false;
}

View File

@ -130,3 +130,13 @@ struct ipset_item * ipset_collection_add(struct ipset_collection_head *head, str
void ipset_collection_destroy(struct ipset_collection_head *head);
struct ipset_item *ipset_collection_search(struct ipset_collection_head *head, const char *filename);
bool ipset_collection_is_empty(const struct ipset_collection_head *head);
struct port_filter_item {
port_filter pf;
LIST_ENTRY(port_filter_item) next;
};
LIST_HEAD(port_filters_head, port_filter_item);
bool port_filter_add(struct port_filters_head *head, const port_filter *pf);
void port_filters_destroy(struct port_filters_head *head);
bool port_filters_in_range(const struct port_filters_head *head, uint16_t port);

View File

@ -31,7 +31,7 @@ static bool dp_match(struct desync_profile *dp, const struct sockaddr *dest, con
if ((dest->sa_family==AF_INET && !dp->filter_ipv4) || (dest->sa_family==AF_INET6 && !dp->filter_ipv6))
// L3 filter does not match
return false;
if (!pf_in_range(saport(dest), &dp->pf_tcp))
if (!port_filters_in_range(&dp->pf_tcp,saport(dest)))
// L4 filter does not match
return false;
if (dp->filter_l7 && !l7_proto_match(l7proto, dp->filter_l7))
@ -96,6 +96,8 @@ void tamper_out(t_ctrack *ctrack, const struct sockaddr *dest, uint8_t *segment,
DBGPRINT("tamper_out\n");
if (!ctrack->dp) return;
if (params.debug)
{
char ip_port[48];
@ -189,8 +191,6 @@ void tamper_out(t_ctrack *ctrack, const struct sockaddr *dest, uint8_t *segment,
}
}
if (!ctrack->dp) return;
switch(l7proto)
{
case HTTP:

View File

@ -164,7 +164,7 @@ static void exithelp(void)
"\nMULTI-STRATEGY:\n"
" --new\t\t\t\t\t; begin new strategy\n"
" --filter-l3=ipv4|ipv6\t\t\t; L3 protocol filter. multiple comma separated values allowed.\n"
" --filter-tcp=[~]port1[-port2]\t\t; TCP port filter. ~ means negation\n"
" --filter-tcp=[~]port1[-port2]|*\t; TCP port filter. ~ means negation. multiple comma separated values allowed.\n"
" --filter-l7=[http|tls|unknown]\t\t; L6-L7 protocol filter. multiple comma separated values allowed.\n"
" --ipset=<filename>\t\t\t; ipset include filter (one ip/CIDR per line, ipv4 and ipv6 accepted, gzip supported, multiple ipsets allowed)\n"
" --ipset-exclude=<filename>\t\t; ipset exclude filter (one ip/CIDR per line, ipv4 and ipv6 accepted, gzip supported, multiple ipsets allowed)\n"
@ -299,10 +299,7 @@ static bool wf_make_l3(char *opt, bool *ipv4, bool *ipv6)
*ipv6 = true;
else return false;
if (e)
{
*e++=c;
}
if (e) *e++=c;
p = e;
}
return true;
@ -328,15 +325,34 @@ static bool parse_l7_list(char *opt, uint32_t *l7)
*l7 |= L7_PROTO_UNKNOWN;
else return false;
if (e)
{
*e++=c;
}
if (e) *e++=c;
p = e;
}
return true;
}
static bool parse_pf_list(char *opt, struct port_filters_head *pfl)
{
char *e,*p,c;
port_filter pf;
for (p=opt ; p ; )
{
if ((e = strchr(p,',')))
{
c=*e;
*e=0;
}
if (!pf_parse(p,&pf) || !port_filter_add(pfl,&pf)) return false;
if (e) *e++=c;
p = e;
}
return true;
}
void parse_params(int argc, char *argv[])
{
int option_index = 0;
@ -954,7 +970,7 @@ void parse_params(int argc, char *argv[])
}
break;
case 58: /* filter-tcp */
if (!pf_parse(optarg,&dp->pf_tcp))
if (!parse_pf_list(optarg,&dp->pf_tcp))
{
DLOG_ERR("Invalid port filter : %s\n",optarg);
exit_clean(1);