mirror of
https://git.proxmox.com/git/mirror_iproute2
synced 2025-10-05 17:15:45 +00:00
ss: Replace unixstat struct by new sockstat struct
Signed-off-by: Vadim Kochan <vadim4j@gmail.com>
This commit is contained in:
parent
89f634f917
commit
ec4d0d8a9d
141
misc/ss.c
141
misc/ss.c
@ -661,6 +661,18 @@ static int get_slabstat(struct slabstat *s)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline void sock_addr_set_str(inet_prefix *prefix, char **ptr)
|
||||||
|
{
|
||||||
|
memcpy(prefix->data, ptr, sizeof(char *));
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline char *sock_addr_get_str(const inet_prefix *prefix)
|
||||||
|
{
|
||||||
|
char *tmp ;
|
||||||
|
memcpy(&tmp, prefix->data, sizeof(char *));
|
||||||
|
return tmp;
|
||||||
|
}
|
||||||
|
|
||||||
static const char *sstate_name[] = {
|
static const char *sstate_name[] = {
|
||||||
"UNKNOWN",
|
"UNKNOWN",
|
||||||
[SS_ESTABLISHED] = "ESTAB",
|
[SS_ESTABLISHED] = "ESTAB",
|
||||||
@ -693,7 +705,8 @@ static const char *sstate_namel[] = {
|
|||||||
|
|
||||||
struct sockstat
|
struct sockstat
|
||||||
{
|
{
|
||||||
uint8_t type;
|
struct sockstat *next;
|
||||||
|
unsigned int type;
|
||||||
uint16_t prot;
|
uint16_t prot;
|
||||||
inet_prefix local;
|
inet_prefix local;
|
||||||
inet_prefix remote;
|
inet_prefix remote;
|
||||||
@ -997,9 +1010,9 @@ static int inet2_addr_match(const inet_prefix *a, const inet_prefix *p,
|
|||||||
|
|
||||||
static int unix_match(const inet_prefix *a, const inet_prefix *p)
|
static int unix_match(const inet_prefix *a, const inet_prefix *p)
|
||||||
{
|
{
|
||||||
char *addr, *pattern;
|
char *addr = sock_addr_get_str(a);
|
||||||
memcpy(&addr, a->data, sizeof(addr));
|
char *pattern = sock_addr_get_str(p);
|
||||||
memcpy(&pattern, p->data, sizeof(pattern));
|
|
||||||
if (pattern == NULL)
|
if (pattern == NULL)
|
||||||
return 1;
|
return 1;
|
||||||
if (addr == NULL)
|
if (addr == NULL)
|
||||||
@ -1015,8 +1028,7 @@ static int run_ssfilter(struct ssfilter *f, struct sockstat *s)
|
|||||||
static int low, high=65535;
|
static int low, high=65535;
|
||||||
|
|
||||||
if (s->local.family == AF_UNIX) {
|
if (s->local.family == AF_UNIX) {
|
||||||
char *p;
|
char *p = sock_addr_get_str(&s->local);
|
||||||
memcpy(&p, s->local.data, sizeof(p));
|
|
||||||
return p == NULL || (p[0] == '@' && strlen(p) == 6 &&
|
return p == NULL || (p[0] == '@' && strlen(p) == 6 &&
|
||||||
strspn(p+1, "0123456789abcdef") == 5);
|
strspn(p+1, "0123456789abcdef") == 5);
|
||||||
}
|
}
|
||||||
@ -1336,7 +1348,7 @@ void *parse_hostcond(char *addr)
|
|||||||
addr+=5;
|
addr+=5;
|
||||||
p = strdup(addr);
|
p = strdup(addr);
|
||||||
a.addr.bitlen = 8*strlen(p);
|
a.addr.bitlen = 8*strlen(p);
|
||||||
memcpy(a.addr.data, &p, sizeof(p));
|
sock_addr_set_str(&a.addr, &p);
|
||||||
fam = AF_UNIX;
|
fam = AF_UNIX;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
@ -2427,31 +2439,21 @@ outerr:
|
|||||||
} while (0);
|
} while (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct unixstat
|
|
||||||
{
|
|
||||||
struct unixstat *next;
|
|
||||||
int ino;
|
|
||||||
int peer;
|
|
||||||
char *peer_name;
|
|
||||||
int rq;
|
|
||||||
int wq;
|
|
||||||
int state;
|
|
||||||
int type;
|
|
||||||
char *name;
|
|
||||||
};
|
|
||||||
|
|
||||||
int unix_state_map[] = { SS_CLOSE, SS_SYN_SENT,
|
int unix_state_map[] = { SS_CLOSE, SS_SYN_SENT,
|
||||||
SS_ESTABLISHED, SS_CLOSING };
|
SS_ESTABLISHED, SS_CLOSING };
|
||||||
|
|
||||||
#define MAX_UNIX_REMEMBER (1024*1024/sizeof(struct unixstat))
|
#define MAX_UNIX_REMEMBER (1024*1024/sizeof(struct sockstat))
|
||||||
|
|
||||||
static void unix_list_free(struct unixstat *list)
|
static void unix_list_free(struct sockstat *list)
|
||||||
{
|
{
|
||||||
while (list) {
|
while (list) {
|
||||||
struct unixstat *s = list;
|
struct sockstat *s = list;
|
||||||
|
char *name = sock_addr_get_str(&s->local);
|
||||||
|
|
||||||
list = list->next;
|
list = list->next;
|
||||||
if (s->name)
|
|
||||||
free(s->name);
|
if (name)
|
||||||
|
free(name);
|
||||||
free(s);
|
free(s);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2475,7 +2477,7 @@ static const char *unix_netid_name(int type)
|
|||||||
return netid;
|
return netid;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool unix_type_skip(struct unixstat *s, struct filter *f)
|
static bool unix_type_skip(struct sockstat *s, struct filter *f)
|
||||||
{
|
{
|
||||||
if (s->type == SOCK_STREAM && !(f->dbs&(1<<UNIX_ST_DB)))
|
if (s->type == SOCK_STREAM && !(f->dbs&(1<<UNIX_ST_DB)))
|
||||||
return true;
|
return true;
|
||||||
@ -2486,44 +2488,49 @@ static bool unix_type_skip(struct unixstat *s, struct filter *f)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void unix_stats_print(struct unixstat *list, struct filter *f)
|
static bool unix_use_proc(void)
|
||||||
{
|
{
|
||||||
struct unixstat *s;
|
return getenv("PROC_NET_UNIX") || getenv("PROC_ROOT");
|
||||||
char *peer;
|
}
|
||||||
|
|
||||||
|
static void unix_stats_print(struct sockstat *list, struct filter *f)
|
||||||
|
{
|
||||||
|
struct sockstat *s;
|
||||||
|
char *local, *peer;
|
||||||
|
bool use_proc = unix_use_proc();
|
||||||
|
|
||||||
for (s = list; s; s = s->next) {
|
for (s = list; s; s = s->next) {
|
||||||
if (!(f->states & (1<<s->state)))
|
if (!(f->states & (1 << s->state)))
|
||||||
continue;
|
continue;
|
||||||
if (unix_type_skip(s, f))
|
if (unix_type_skip(s, f))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
peer = "*";
|
local = sock_addr_get_str(&s->local);
|
||||||
if (s->peer_name)
|
peer = "*";
|
||||||
peer = s->peer_name;
|
|
||||||
|
if (s->rport && use_proc) {
|
||||||
|
struct sockstat *p;
|
||||||
|
|
||||||
if (s->peer && !s->peer_name) {
|
|
||||||
struct unixstat *p;
|
|
||||||
for (p = list; p; p = p->next) {
|
for (p = list; p; p = p->next) {
|
||||||
if (s->peer == p->ino)
|
if (s->rport == p->lport)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!p) {
|
if (!p) {
|
||||||
peer = "?";
|
peer = "?";
|
||||||
} else {
|
} else {
|
||||||
peer = p->name ? : "*";
|
peer = sock_addr_get_str(&p->local);
|
||||||
|
peer = peer ? : "*";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (f->f) {
|
if (f->f) {
|
||||||
struct sockstat st;
|
|
||||||
st.local.family = AF_UNIX;
|
|
||||||
st.remote.family = AF_UNIX;
|
|
||||||
memcpy(st.local.data, &s->name, sizeof(s->name));
|
|
||||||
if (strcmp(peer, "*") == 0)
|
if (strcmp(peer, "*") == 0)
|
||||||
memset(st.remote.data, 0, sizeof(peer));
|
memset(s->remote.data, 0, sizeof(char *));
|
||||||
else
|
else
|
||||||
memcpy(st.remote.data, &peer, sizeof(peer));
|
sock_addr_set_str(&s->remote, &peer);
|
||||||
if (run_ssfilter(f->f, &st) == 0)
|
|
||||||
|
if (run_ssfilter(f->f, s) == 0)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2534,8 +2541,8 @@ static void unix_stats_print(struct unixstat *list, struct filter *f)
|
|||||||
printf("%-*s ", state_width, sstate_name[s->state]);
|
printf("%-*s ", state_width, sstate_name[s->state]);
|
||||||
printf("%-6d %-6d ", s->rq, s->wq);
|
printf("%-6d %-6d ", s->rq, s->wq);
|
||||||
printf("%*s %-*d %*s %-*d",
|
printf("%*s %-*d %*s %-*d",
|
||||||
addr_width, s->name ? : "*", serv_width, s->ino,
|
addr_width, local ? : "*", serv_width,
|
||||||
addr_width, peer, serv_width, s->peer);
|
s->lport, addr_width, peer, serv_width, s->rport);
|
||||||
char *buf = NULL;
|
char *buf = NULL;
|
||||||
|
|
||||||
if (show_proc_ctx || show_sock_ctx) {
|
if (show_proc_ctx || show_sock_ctx) {
|
||||||
@ -2561,15 +2568,16 @@ static int unix_show_sock(const struct sockaddr_nl *addr, struct nlmsghdr *nlh,
|
|||||||
struct filter *f = (struct filter *)arg;
|
struct filter *f = (struct filter *)arg;
|
||||||
struct unix_diag_msg *r = NLMSG_DATA(nlh);
|
struct unix_diag_msg *r = NLMSG_DATA(nlh);
|
||||||
struct rtattr *tb[UNIX_DIAG_MAX+1];
|
struct rtattr *tb[UNIX_DIAG_MAX+1];
|
||||||
char name[128];
|
char *name = NULL;
|
||||||
struct unixstat stat = { .name = "*" , .peer_name = "*" };
|
struct sockstat stat = {};
|
||||||
|
|
||||||
parse_rtattr(tb, UNIX_DIAG_MAX, (struct rtattr*)(r+1),
|
parse_rtattr(tb, UNIX_DIAG_MAX, (struct rtattr*)(r+1),
|
||||||
nlh->nlmsg_len - NLMSG_LENGTH(sizeof(*r)));
|
nlh->nlmsg_len - NLMSG_LENGTH(sizeof(*r)));
|
||||||
|
|
||||||
stat.type = r->udiag_type;
|
stat.type = r->udiag_type;
|
||||||
stat.state = r->udiag_state;
|
stat.state = r->udiag_state;
|
||||||
stat.ino = r->udiag_ino;
|
stat.ino = stat.lport = r->udiag_ino;
|
||||||
|
stat.local.family = stat.remote.family = AF_UNIX;
|
||||||
|
|
||||||
if (unix_type_skip(&stat, f))
|
if (unix_type_skip(&stat, f))
|
||||||
return 0;
|
return 0;
|
||||||
@ -2582,14 +2590,15 @@ static int unix_show_sock(const struct sockaddr_nl *addr, struct nlmsghdr *nlh,
|
|||||||
if (tb[UNIX_DIAG_NAME]) {
|
if (tb[UNIX_DIAG_NAME]) {
|
||||||
int len = RTA_PAYLOAD(tb[UNIX_DIAG_NAME]);
|
int len = RTA_PAYLOAD(tb[UNIX_DIAG_NAME]);
|
||||||
|
|
||||||
|
name = malloc(len + 1);
|
||||||
memcpy(name, RTA_DATA(tb[UNIX_DIAG_NAME]), len);
|
memcpy(name, RTA_DATA(tb[UNIX_DIAG_NAME]), len);
|
||||||
name[len] = '\0';
|
name[len] = '\0';
|
||||||
if (name[0] == '\0')
|
if (name[0] == '\0')
|
||||||
name[0] = '@';
|
name[0] = '@';
|
||||||
stat.name = &name[0];
|
sock_addr_set_str(&stat.local, &name);
|
||||||
}
|
}
|
||||||
if (tb[UNIX_DIAG_PEER])
|
if (tb[UNIX_DIAG_PEER])
|
||||||
stat.peer = rta_getattr_u32(tb[UNIX_DIAG_PEER]);
|
stat.rport = rta_getattr_u32(tb[UNIX_DIAG_PEER]);
|
||||||
|
|
||||||
unix_stats_print(&stat, f);
|
unix_stats_print(&stat, f);
|
||||||
|
|
||||||
@ -2606,6 +2615,9 @@ static int unix_show_sock(const struct sockaddr_nl *addr, struct nlmsghdr *nlh,
|
|||||||
}
|
}
|
||||||
if (show_mem || show_details)
|
if (show_mem || show_details)
|
||||||
printf("\n");
|
printf("\n");
|
||||||
|
|
||||||
|
if (name)
|
||||||
|
free(name);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2652,13 +2664,12 @@ static int unix_show(struct filter *f)
|
|||||||
char name[128];
|
char name[128];
|
||||||
int newformat = 0;
|
int newformat = 0;
|
||||||
int cnt;
|
int cnt;
|
||||||
struct unixstat *list = NULL;
|
struct sockstat *list = NULL;
|
||||||
|
|
||||||
if (!filter_af_get(f, AF_UNIX))
|
if (!filter_af_get(f, AF_UNIX))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (!getenv("PROC_NET_UNIX") && !getenv("PROC_ROOT")
|
if (!unix_use_proc() && unix_show_netlink(f) == 0)
|
||||||
&& unix_show_netlink(f) == 0)
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if ((fp = net_unix_open()) == NULL)
|
if ((fp = net_unix_open()) == NULL)
|
||||||
@ -2670,31 +2681,30 @@ static int unix_show(struct filter *f)
|
|||||||
cnt = 0;
|
cnt = 0;
|
||||||
|
|
||||||
while (fgets(buf, sizeof(buf)-1, fp)) {
|
while (fgets(buf, sizeof(buf)-1, fp)) {
|
||||||
struct unixstat *u, **insp;
|
struct sockstat *u, **insp;
|
||||||
int flags;
|
int flags;
|
||||||
|
|
||||||
if (!(u = malloc(sizeof(*u))))
|
if (!(u = malloc(sizeof(*u))))
|
||||||
break;
|
break;
|
||||||
u->name = NULL;
|
|
||||||
u->peer_name = NULL;
|
|
||||||
|
|
||||||
if (sscanf(buf, "%x: %x %x %x %x %x %d %s",
|
if (sscanf(buf, "%x: %x %x %x %x %x %d %s",
|
||||||
&u->peer, &u->rq, &u->wq, &flags, &u->type,
|
&u->rport, &u->rq, &u->wq, &flags, &u->type,
|
||||||
&u->state, &u->ino, name) < 8)
|
&u->state, &u->ino, name) < 8)
|
||||||
name[0] = 0;
|
name[0] = 0;
|
||||||
|
|
||||||
if (flags&(1<<16)) {
|
u->lport = u->ino;
|
||||||
|
u->local.family = u->remote.family = AF_UNIX;
|
||||||
|
|
||||||
|
if (flags & (1 << 16)) {
|
||||||
u->state = SS_LISTEN;
|
u->state = SS_LISTEN;
|
||||||
} else {
|
} else {
|
||||||
u->state = unix_state_map[u->state-1];
|
u->state = unix_state_map[u->state-1];
|
||||||
if (u->type == SOCK_DGRAM &&
|
if (u->type == SOCK_DGRAM && u->state == SS_CLOSE && u->rport)
|
||||||
u->state == SS_CLOSE &&
|
|
||||||
u->peer)
|
|
||||||
u->state = SS_ESTABLISHED;
|
u->state = SS_ESTABLISHED;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!newformat) {
|
if (!newformat) {
|
||||||
u->peer = 0;
|
u->rport = 0;
|
||||||
u->rq = 0;
|
u->rq = 0;
|
||||||
u->wq = 0;
|
u->wq = 0;
|
||||||
}
|
}
|
||||||
@ -2711,9 +2721,8 @@ static int unix_show(struct filter *f)
|
|||||||
*insp = u;
|
*insp = u;
|
||||||
|
|
||||||
if (name[0]) {
|
if (name[0]) {
|
||||||
if ((u->name = malloc(strlen(name)+1)) == NULL)
|
char *tmp = strdup(name);
|
||||||
break;
|
sock_addr_set_str(&u->local, &tmp);
|
||||||
strcpy(u->name, name);
|
|
||||||
}
|
}
|
||||||
if (++cnt > MAX_UNIX_REMEMBER) {
|
if (++cnt > MAX_UNIX_REMEMBER) {
|
||||||
unix_stats_print(list, f);
|
unix_stats_print(list, f);
|
||||||
|
Loading…
Reference in New Issue
Block a user