4 #include <netinet/in.h>
5 #include <linux/netlink.h>
6 #include <linux/sock_diag.h>
7 #include <linux/inet_diag.h>
10 send_query(const int fd, const int family, const int proto)
12 struct sockaddr_nl nladdr = {
13 .nl_family = AF_NETLINK
17 struct inet_diag_req_v2 idr;
20 .nlmsg_len = sizeof(req),
21 .nlmsg_type = SOCK_DIAG_BY_FAMILY,
22 .nlmsg_flags = NLM_F_DUMP | NLM_F_REQUEST
25 .sdiag_family = family,
26 .sdiag_protocol = proto,
32 .iov_len = sizeof(req)
35 .msg_name = (void*)&nladdr,
36 .msg_namelen = sizeof(nladdr),
41 return sendmsg(fd, &msg, 0) > 0;
45 check_responses(const int fd)
47 static char buf[8192];
48 struct sockaddr_nl nladdr = {
49 .nl_family = AF_NETLINK
53 .iov_len = sizeof(buf)
56 .msg_name = (void*)&nladdr,
57 .msg_namelen = sizeof(nladdr),
62 ssize_t ret = recvmsg(fd, &msg, 0);
66 struct nlmsghdr *h = (struct nlmsghdr*)buf;
67 return (NLMSG_OK(h, ret) &&
68 h->nlmsg_type != NLMSG_ERROR &&
69 h->nlmsg_type != NLMSG_DONE) ? 1 : 0;
74 struct sockaddr_in addr;
75 socklen_t len = sizeof(addr);
77 memset(&addr, 0, sizeof(addr));
78 addr.sin_family = AF_INET;
79 addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
84 if (socket(PF_INET, SOCK_STREAM, 0) ||
85 bind(0, (struct sockaddr *) &addr, len) ||
87 socket(AF_NETLINK, SOCK_RAW, NETLINK_INET_DIAG) != 1)
90 return (send_query(1, AF_INET, IPPROTO_TCP) &&
91 check_responses(1)) ? 0 : 77;