parse_rtattr(tb, INET_DIAG_MAX, (struct rtattr*)(r+1),
nlh->nlmsg_len - NLMSG_LENGTH(sizeof(*r)));
- if (tb[INET_DIAG_MEMINFO]) {
+ if (tb[INET_DIAG_SKMEMINFO]) {
+ const __u32 *skmeminfo = RTA_DATA(tb[INET_DIAG_SKMEMINFO]);
+ printf(" skmem:(r%u,rb%u,t%u,tb%u,f%u,w%u,o%u)",
+ skmeminfo[SK_MEMINFO_RMEM_ALLOC],
+ skmeminfo[SK_MEMINFO_RCVBUF],
+ skmeminfo[SK_MEMINFO_WMEM_ALLOC],
+ skmeminfo[SK_MEMINFO_SNDBUF],
+ skmeminfo[SK_MEMINFO_FWD_ALLOC],
+ skmeminfo[SK_MEMINFO_WMEM_QUEUED],
+ skmeminfo[SK_MEMINFO_OPTMEM]);
+ }else if (tb[INET_DIAG_MEMINFO]) {
const struct inet_diag_meminfo *minfo
= RTA_DATA(tb[INET_DIAG_MEMINFO]);
printf(" mem:(r%u,w%u,f%u,t%u)",
}
if (tb[INET_DIAG_CONG])
- printf(" %s", (char *) RTA_DATA(tb[INET_DIAG_CONG]));
+ printf(" %s", rta_getattr_str(tb[INET_DIAG_CONG]));
if (info->tcpi_options & TCPI_OPT_WSCALE)
printf(" wscale:%d,%d", info->tcpi_snd_wscale,
memset(&req.r, 0, sizeof(req.r));
req.r.idiag_family = AF_INET;
req.r.idiag_states = f->states;
- if (show_mem)
+ if (show_mem) {
req.r.idiag_ext |= (1<<(INET_DIAG_MEMINFO-1));
+ req.r.idiag_ext |= (1<<(INET_DIAG_SKMEMINFO-1));
+ }
if (show_tcpinfo) {
req.r.idiag_ext |= (1<<(INET_DIAG_INFO-1));
.msg_iovlen = f->f ? 3 : 1,
};
- if (sendmsg(fd, &msg, 0) < 0)
+ if (sendmsg(fd, &msg, 0) < 0) {
+ close(fd);
return -1;
+ }
iov[0] = (struct iovec){
.iov_base = buf,
}
if (status == 0) {
fprintf(stderr, "EOF on netlink\n");
+ close(fd);
return 0;
}
h->nlmsg_seq != 123456)
goto skip_it;
- if (h->nlmsg_type == NLMSG_DONE)
+ if (h->nlmsg_type == NLMSG_DONE) {
+ close(fd);
return 0;
+ }
if (h->nlmsg_type == NLMSG_ERROR) {
struct nlmsgerr *err = (struct nlmsgerr*)NLMSG_DATA(h);
if (h->nlmsg_len < NLMSG_LENGTH(sizeof(struct nlmsgerr))) {
fprintf(stderr, "ERROR truncated\n");
} else {
errno = -err->error;
+ if (errno == EOPNOTSUPP) {
+ close(fd);
+ return -1;
+ }
perror("TCPDIAG answers");
}
+ close(fd);
return 0;
}
if (!dump_fp) {
continue;
}
err = tcp_show_sock(h, NULL);
- if (err < 0)
+ if (err < 0) {
+ close(fd);
return err;
+ }
}
skip_it:
exit(1);
}
}
+ close(fd);
return 0;
}
static int unix_show_netlink(struct filter *f, FILE *dump_fp)
{
int fd;
- struct sockaddr_nl nladdr;
struct {
struct nlmsghdr nlh;
struct unix_diag_req r;
} req;
- struct msghdr msg;
char buf[8192];
- struct iovec iov[3];
if ((fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_INET_DIAG)) < 0)
return -1;
- memset(&nladdr, 0, sizeof(nladdr));
- nladdr.nl_family = AF_NETLINK;
-
+ memset(&req, 0, sizeof(req));
req.nlh.nlmsg_len = sizeof(req);
req.nlh.nlmsg_type = SOCK_DIAG_BY_FAMILY;
req.nlh.nlmsg_flags = NLM_F_ROOT|NLM_F_MATCH|NLM_F_REQUEST;
- req.nlh.nlmsg_pid = 0;
req.nlh.nlmsg_seq = 123456;
- memset(&req.r, 0, sizeof(req.r));
+
req.r.sdiag_family = AF_UNIX;
- req.r.sdiag_protocol = 0; /* ignored */
req.r.udiag_states = f->states;
req.r.udiag_show = UDIAG_SHOW_NAME | UDIAG_SHOW_PEER | UDIAG_SHOW_RQLEN;
- iov[0] = (struct iovec){
- .iov_base = &req,
- .iov_len = sizeof(req)
- };
-
- msg = (struct msghdr) {
- .msg_name = (void*)&nladdr,
- .msg_namelen = sizeof(nladdr),
- .msg_iov = iov,
- .msg_iovlen = f->f ? 3 : 1,
- };
-
- if (sendmsg(fd, &msg, 0) < 0) {
+ if (send(fd, &req, sizeof(req), 0) < 0) {
close(fd);
return -1;
}
- iov[0] = (struct iovec){
- .iov_base = buf,
- .iov_len = sizeof(buf)
- };
-
while (1) {
- int status;
+ ssize_t status;
struct nlmsghdr *h;
+ struct sockaddr_nl nladdr;
+ socklen_t slen = sizeof(nladdr);
- msg = (struct msghdr) {
- (void*)&nladdr, sizeof(nladdr),
- iov, 1,
- NULL, 0,
- 0
- };
-
- status = recvmsg(fd, &msg, 0);
-
+ status = recvfrom(fd, buf, sizeof(buf), 0,
+ (struct sockaddr *) &nladdr, &slen);
if (status < 0) {
if (errno == EINTR)
continue;
}
if (status == 0) {
fprintf(stderr, "EOF on netlink\n");
- close(fd);
- return 0;
+ goto close_it;
}
if (dump_fp)
h->nlmsg_seq != 123456)
goto skip_it;
- if (h->nlmsg_type == NLMSG_DONE) {
- close(fd);
- return 0;
- }
+ if (h->nlmsg_type == NLMSG_DONE)
+ goto close_it;
+
if (h->nlmsg_type == NLMSG_ERROR) {
struct nlmsgerr *err = (struct nlmsgerr*)NLMSG_DATA(h);
if (h->nlmsg_len < NLMSG_LENGTH(sizeof(struct nlmsgerr))) {
skip_it:
h = NLMSG_NEXT(h, status);
}
- if (msg.msg_flags & MSG_TRUNC) {
- fprintf(stderr, "Message truncated\n");
- continue;
- }
+
if (status) {
- fprintf(stderr, "!!!Remnant of size %d\n", status);
+ fprintf(stderr, "!!!Remnant of size %zd\n", status);
exit(1);
}
}
+
+close_it:
close(fd);
return 0;
}