From: Stephen Hemminger Date: Fri, 17 Feb 2012 00:42:42 +0000 (-0800) Subject: ss: simplify code X-Git-Url: https://rtime.felk.cvut.cz/gitweb/lisovros/iproute2_canprio.git/commitdiff_plain/2728f598bbeb6d4b7cc7f65a774ab70fdca04ab4 ss: simplify code Rather than copy-pasting code using sendmsg/recvmsg, use the simpler send() and recv() system calls. --- diff --git a/misc/ss.c b/misc/ss.c index 2caac4a..5414f75 100644 --- a/misc/ss.c +++ b/misc/ss.c @@ -2061,67 +2061,38 @@ static int unix_show_sock(struct nlmsghdr *nlh, struct filter *f) 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; @@ -2130,8 +2101,7 @@ static int unix_show_netlink(struct filter *f, FILE *dump_fp) } if (status == 0) { fprintf(stderr, "EOF on netlink\n"); - close(fd); - return 0; + goto close_it; } if (dump_fp) @@ -2145,10 +2115,9 @@ static int unix_show_netlink(struct filter *f, FILE *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))) { @@ -2172,15 +2141,14 @@ static int unix_show_netlink(struct filter *f, FILE *dump_fp) 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; }