ss: Fix wrong filter behaviour
Fixed applying family & socket type filters. It was not possible to select UDP & UNIX sockets together. Now selected families are ORed. The problem was that filters were combined by AND. Signed-off-by: Vadim Kochan <vadim4j@gmail.com> Reported-By: Mihai Moldovan <ionic@ionic.de>
This commit is contained in:
parent
d937a74b6d
commit
57ff5a1096
95
misc/ss.c
95
misc/ss.c
|
|
@ -233,14 +233,12 @@ static struct filter current_filter;
|
|||
static void filter_db_set(struct filter *f, int db)
|
||||
{
|
||||
f->states |= default_dbs[db].states;
|
||||
f->families |= default_dbs[db].families;
|
||||
f->dbs |= 1 << db;
|
||||
do_default = 0;
|
||||
}
|
||||
|
||||
static void filter_af_set(struct filter *f, int af)
|
||||
{
|
||||
f->dbs |= default_afs[af].dbs;
|
||||
f->states |= default_afs[af].states;
|
||||
f->families |= 1 << af;
|
||||
do_default = 0;
|
||||
|
|
@ -266,21 +264,31 @@ static void filter_default_dbs(struct filter *f)
|
|||
filter_db_set(f, NETLINK_DB);
|
||||
}
|
||||
|
||||
static void filter_merge(struct filter *af, struct filter *dbf, int states)
|
||||
static void filter_states_set(struct filter *f, int states)
|
||||
{
|
||||
if (af->families)
|
||||
af->families = (af->families | dbf->families) & af->families;
|
||||
else
|
||||
af->families = dbf->families;
|
||||
|
||||
if (dbf->dbs)
|
||||
af->dbs = (af->dbs | dbf->dbs) & dbf->dbs;
|
||||
|
||||
if (dbf->states)
|
||||
af->states = (af->states | dbf->states) & dbf->states;
|
||||
|
||||
if (states)
|
||||
af->states = (af->states | states) & states;
|
||||
f->states = (f->states | states) & states;
|
||||
}
|
||||
|
||||
static void filter_merge_defaults(struct filter *f)
|
||||
{
|
||||
int db;
|
||||
int af;
|
||||
|
||||
for (db = 0; db < MAX_DB; db++) {
|
||||
if (!(f->dbs & (1 << db)))
|
||||
continue;
|
||||
|
||||
if (!(default_dbs[db].families & f->families))
|
||||
f->families |= default_dbs[db].families;
|
||||
}
|
||||
for (af = 0; af < AF_MAX; af++) {
|
||||
if (!(f->families & (1 << af)))
|
||||
continue;
|
||||
|
||||
if (!(default_afs[af].dbs & f->dbs))
|
||||
f->dbs |= default_afs[af].dbs;
|
||||
}
|
||||
}
|
||||
|
||||
static FILE *generic_proc_open(const char *env, const char *name)
|
||||
|
|
@ -1534,7 +1542,7 @@ out:
|
|||
if (fam != AF_UNSPEC) {
|
||||
f->families = 0;
|
||||
filter_af_set(f, fam);
|
||||
filter_merge(f, f, 0);
|
||||
filter_states_set(f, 0);
|
||||
}
|
||||
|
||||
res = malloc(sizeof(*res));
|
||||
|
|
@ -3416,7 +3424,6 @@ int main(int argc, char *argv[])
|
|||
const char *dump_tcpdiag = NULL;
|
||||
FILE *filter_fp = NULL;
|
||||
int ch;
|
||||
struct filter dbs_filter = {};
|
||||
int state_filter = 0;
|
||||
|
||||
while ((ch = getopt_long(argc, argv, "dhaletuwxnro460spbf:miA:D:F:vVzZN:",
|
||||
|
|
@ -3450,16 +3457,16 @@ int main(int argc, char *argv[])
|
|||
show_bpf++;
|
||||
break;
|
||||
case 'd':
|
||||
filter_db_set(&dbs_filter, DCCP_DB);
|
||||
filter_db_set(¤t_filter, DCCP_DB);
|
||||
break;
|
||||
case 't':
|
||||
filter_db_set(&dbs_filter, TCP_DB);
|
||||
filter_db_set(¤t_filter, TCP_DB);
|
||||
break;
|
||||
case 'u':
|
||||
filter_db_set(&dbs_filter, UDP_DB);
|
||||
filter_db_set(¤t_filter, UDP_DB);
|
||||
break;
|
||||
case 'w':
|
||||
filter_db_set(&dbs_filter, RAW_DB);
|
||||
filter_db_set(¤t_filter, RAW_DB);
|
||||
break;
|
||||
case 'x':
|
||||
filter_af_set(¤t_filter, AF_UNIX);
|
||||
|
|
@ -3511,44 +3518,44 @@ int main(int argc, char *argv[])
|
|||
if ((p1 = strchr(p, ',')) != NULL)
|
||||
*p1 = 0;
|
||||
if (strcmp(p, "all") == 0) {
|
||||
filter_default_dbs(&dbs_filter);
|
||||
filter_default_dbs(¤t_filter);
|
||||
} else if (strcmp(p, "inet") == 0) {
|
||||
filter_db_set(&dbs_filter, UDP_DB);
|
||||
filter_db_set(&dbs_filter, DCCP_DB);
|
||||
filter_db_set(&dbs_filter, TCP_DB);
|
||||
filter_db_set(&dbs_filter, RAW_DB);
|
||||
filter_db_set(¤t_filter, UDP_DB);
|
||||
filter_db_set(¤t_filter, DCCP_DB);
|
||||
filter_db_set(¤t_filter, TCP_DB);
|
||||
filter_db_set(¤t_filter, RAW_DB);
|
||||
} else if (strcmp(p, "udp") == 0) {
|
||||
filter_db_set(&dbs_filter, UDP_DB);
|
||||
filter_db_set(¤t_filter, UDP_DB);
|
||||
} else if (strcmp(p, "dccp") == 0) {
|
||||
filter_db_set(&dbs_filter, DCCP_DB);
|
||||
filter_db_set(¤t_filter, DCCP_DB);
|
||||
} else if (strcmp(p, "tcp") == 0) {
|
||||
filter_db_set(&dbs_filter, TCP_DB);
|
||||
filter_db_set(¤t_filter, TCP_DB);
|
||||
} else if (strcmp(p, "raw") == 0) {
|
||||
filter_db_set(&dbs_filter, RAW_DB);
|
||||
filter_db_set(¤t_filter, RAW_DB);
|
||||
} else if (strcmp(p, "unix") == 0) {
|
||||
filter_db_set(&dbs_filter, UNIX_ST_DB);
|
||||
filter_db_set(&dbs_filter, UNIX_DG_DB);
|
||||
filter_db_set(&dbs_filter, UNIX_SQ_DB);
|
||||
filter_db_set(¤t_filter, UNIX_ST_DB);
|
||||
filter_db_set(¤t_filter, UNIX_DG_DB);
|
||||
filter_db_set(¤t_filter, UNIX_SQ_DB);
|
||||
} else if (strcasecmp(p, "unix_stream") == 0 ||
|
||||
strcmp(p, "u_str") == 0) {
|
||||
filter_db_set(&dbs_filter, UNIX_ST_DB);
|
||||
filter_db_set(¤t_filter, UNIX_ST_DB);
|
||||
} else if (strcasecmp(p, "unix_dgram") == 0 ||
|
||||
strcmp(p, "u_dgr") == 0) {
|
||||
filter_db_set(&dbs_filter, UNIX_DG_DB);
|
||||
filter_db_set(¤t_filter, UNIX_DG_DB);
|
||||
} else if (strcasecmp(p, "unix_seqpacket") == 0 ||
|
||||
strcmp(p, "u_seq") == 0) {
|
||||
filter_db_set(&dbs_filter, UNIX_SQ_DB);
|
||||
filter_db_set(¤t_filter, UNIX_SQ_DB);
|
||||
} else if (strcmp(p, "packet") == 0) {
|
||||
filter_db_set(&dbs_filter, PACKET_R_DB);
|
||||
filter_db_set(&dbs_filter, PACKET_DG_DB);
|
||||
filter_db_set(¤t_filter, PACKET_R_DB);
|
||||
filter_db_set(¤t_filter, PACKET_DG_DB);
|
||||
} else if (strcmp(p, "packet_raw") == 0 ||
|
||||
strcmp(p, "p_raw") == 0) {
|
||||
filter_db_set(&dbs_filter, PACKET_R_DB);
|
||||
filter_db_set(¤t_filter, PACKET_R_DB);
|
||||
} else if (strcmp(p, "packet_dgram") == 0 ||
|
||||
strcmp(p, "p_dgr") == 0) {
|
||||
filter_db_set(&dbs_filter, PACKET_DG_DB);
|
||||
filter_db_set(¤t_filter, PACKET_DG_DB);
|
||||
} else if (strcmp(p, "netlink") == 0) {
|
||||
filter_db_set(&dbs_filter, NETLINK_DB);
|
||||
filter_db_set(¤t_filter, NETLINK_DB);
|
||||
} else {
|
||||
fprintf(stderr, "ss: \"%s\" is illegal socket table id\n", p);
|
||||
usage();
|
||||
|
|
@ -3641,11 +3648,11 @@ int main(int argc, char *argv[])
|
|||
if (do_default) {
|
||||
state_filter = state_filter ? state_filter : SS_CONN;
|
||||
filter_default_dbs(¤t_filter);
|
||||
filter_merge(¤t_filter, ¤t_filter, state_filter);
|
||||
} else {
|
||||
filter_merge(¤t_filter, &dbs_filter, state_filter);
|
||||
}
|
||||
|
||||
filter_states_set(¤t_filter, state_filter);
|
||||
filter_merge_defaults(¤t_filter);
|
||||
|
||||
if (resolve_services && resolve_hosts &&
|
||||
(current_filter.dbs&(UNIX_DBM|(1<<TCP_DB)|(1<<UDP_DB)|(1<<DCCP_DB))))
|
||||
init_service_resolver();
|
||||
|
|
|
|||
Loading…
Reference in New Issue