#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "libctnetlink.h" #define NETLINK_SOCKBUFSZ 1<<20 int accept_msg(struct sockaddr_nl *who, struct nlmsghdr *n, void *arg) { int udp_sock = *(int *)arg; if (send(udp_sock, n, n->nlmsg_len, 0) < 0) perror("send\n"); return 0; } int main(int argc, char **argv) { struct nfnl_handle nlh; struct sockaddr_in sin; int sock_buf_size = NETLINK_SOCKBUFSZ; int udp_sock; if (argc < 2) { fprintf(stderr, "Usage: %s [ | listen ]\n", argv[0]); exit(1); } if (nfnl_open(&nlh, NFNL_SUBSYS_CTNETLINK, ~NFGRP_IPV4_CT_UDP)) { perror("nfnl_open\n"); exit(1); } if ((udp_sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) { perror("socket\n"); exit(1); } sin.sin_family = AF_INET; sin.sin_port = htons(10000); if (strncmp(argv[1], "listen", sizeof("listen")) == 0) { char buf[4000]; struct nlmsghdr *n = (struct nlmsghdr *)buf; int len; sin.sin_addr.s_addr = 0; if (bind(udp_sock, (struct sockaddr *)&sin, sizeof(sin)) < 0) { perror("bind\n"); exit(1); } while ((len = recv(udp_sock, &buf, sizeof(buf), 0))) { n->nlmsg_flags = NLM_F_REQUEST|NLM_F_CREATE|NLM_F_EXCL; if (nfnl_send(&nlh, n) < 0) perror("nfnl_send\n"); } exit(0); } if (setsockopt(nlh.fd, SOL_SOCKET, SO_RCVBUF, (const char *)&sock_buf_size, sizeof(int)) < 0) { perror("setsockopt\n"); exit(1); } inet_aton(argv[1],&sin.sin_addr.s_addr); if (connect(udp_sock, (struct sockaddr *)&sin, sizeof(sin)) < 0) { perror("connect\n"); exit(1); } if (nfnl_listen(&nlh, accept_msg, &udp_sock) < 0) { perror("nfnl_listen\n"); exit(1); } }