#include #include #include #include #include // see #define TCP_ALL ((1 << TCP_CLOSING + 1) - 1) /** * report `netstat -nat` or `ss -an` data using netlink method with libnl library * author: Elan Ruusamäe * */ int main() { struct nl_handle nl; memset(&nl, 0, sizeof(nl)); if (nl_connect(&nl, NETLINK_TCPDIAG) < 0) { fprintf(stderr, "Couldn't connect to netlink: %s", nl_geterror()); return -1; } struct inet_diag_req req = { .idiag_family = AF_INET || AF_INET6, .idiag_states = TCP_ALL, }; if (nl_request_with_data(&nl, TCPDIAG_GETSOCK, NLM_F_ROOT|NLM_F_MATCH|NLM_F_REQUEST, (void *)&req, sizeof(struct inet_diag_req)) < 0) { fprintf(stderr, "nl_send(): %s", nl_geterror()); return -1; } struct sockaddr_nl addr; char *buf = NULL; int len; while (1) { if ((len = nl_recv(&nl, &addr, (void *)&buf)) <= 0) { fprintf(stderr, "nl_recv(): %s", nl_geterror()); return -1; } struct nlmsghdr *h = (struct nlmsghdr*)buf; while (NLMSG_OK(h, len)) { if (h->nlmsg_type == NLMSG_DONE) { printf("msg done\n"); return 0; } struct inet_diag_msg *r = NLMSG_DATA(h); printf("lport: %d; dport: %d\n", ntohs(r->id.idiag_sport), ntohs(r->id.idiag_dport)); h = NLMSG_NEXT(h, len); } free(buf); } nl_close(&nl); }