#include #include #include #include #include #include "libnetlink.h" #include #include enum { SS_UNKNOWN, SS_ESTABLISHED, SS_SYN_SENT, SS_SYN_RECV, SS_FIN_WAIT1, SS_FIN_WAIT2, SS_TIME_WAIT, SS_CLOSE, SS_CLOSE_WAIT, SS_LAST_ACK, SS_LISTEN, SS_CLOSING, SS_MAX }; #define SS_ALL ((1<idiag_inode); parse_rtattr(tb, LOCAL_MAX, (struct rtattr*)(r+1), nlh->nlmsg_len - NLMSG_LENGTH(sizeof(*r))); if (tb[INET_DIAG_SECCTX]) printf(" %s", (char *) RTA_DATA(tb[INET_DIAG_SECCTX])); printf("\n"); } static int tcp_show_netlink( int socktype) { int fd; struct sockaddr_nl nladdr; struct { struct nlmsghdr nlh; struct inet_diag_req r; } req; struct msghdr msg; struct rtattr rta; 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; req.nlh.nlmsg_len = sizeof(req); req.nlh.nlmsg_type = socktype; 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.idiag_family = AF_INET; req.r.idiag_states = SS_ALL; req.r.idiag_ext |= (1<<(INET_DIAG_SECCTX-1)); 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 = 1, }; if (sendmsg(fd, &msg, 0) < 0) return -1; iov[0] = (struct iovec){ .iov_base = buf, .iov_len = sizeof(buf) }; while (1) { int status; struct nlmsghdr *h; msg = (struct msghdr) { (void*)&nladdr, sizeof(nladdr), iov, 1, NULL, 0, 0 }; status = recvmsg(fd, &msg, 0); if (status < 0) { if (errno == EINTR) continue; perror("OVERRUN"); continue; } if (status == 0) { fprintf(stderr, "EOF on netlink\n"); return 0; } h = (struct nlmsghdr*)buf; while (NLMSG_OK(h, status)) { struct inet_diag_msg *r = NLMSG_DATA(h); if (/*h->nlmsg_pid != rth->local.nl_pid ||*/ h->nlmsg_seq != 123456) goto skip_it; if (h->nlmsg_type == NLMSG_DONE) return 0; if (h->nlmsg_type == NLMSG_ERROR) return 0; tcp_show_info(h, r); skip_it: h = NLMSG_NEXT(h, status); } } return 0; } void main() { tcp_show_netlink( TCPDIAG_GETSOCK); }