static struct mnl_socket *msg_send(struct nlmsghdr *nlh) { int ret; struct mnl_socket *nl; nl = mnl_socket_open(NETLINK_GENERIC); if (nl == NULL) { perror("mnl_socket_open"); return NULL; } ret = mnl_socket_bind(nl, 0, MNL_SOCKET_AUTOPID); if (ret < 0) { perror("mnl_socket_bind"); return NULL; } ret = mnl_socket_sendto(nl, nlh, nlh->nlmsg_len); if (ret < 0) { perror("mnl_socket_send"); return NULL; } return nl; }
int main(void) { struct mnl_socket *nl; char buf[MNL_SOCKET_BUFFER_SIZE]; int ret; nl = mnl_socket_open(NETLINK_ROUTE); if (nl == NULL) { perror("mnl_socket_open"); exit(EXIT_FAILURE); } if (mnl_socket_bind(nl, RTMGRP_LINK, MNL_SOCKET_AUTOPID) < 0) { perror("mnl_socket_bind"); exit(EXIT_FAILURE); } ret = mnl_socket_recvfrom(nl, buf, sizeof(buf)); while (ret > 0) { ret = mnl_cb_run(buf, ret, 0, 0, data_cb, NULL); if (ret <= 0) break; ret = mnl_socket_recvfrom(nl, buf, sizeof(buf)); } if (ret == -1) { perror("error"); exit(EXIT_FAILURE); } mnl_socket_close(nl); return 0; }
int main(int argc, char *argv[]) { struct mnl_socket *nl; char buf[MNL_SOCKET_BUFFER_SIZE]; struct nlmsghdr *nlh; struct genlmsghdr *genl; int ret; unsigned int seq, portid; if (argc != 2) { printf("%s [family name]\n", argv[0]); exit(EXIT_FAILURE); } nlh = mnl_nlmsg_put_header(buf); nlh->nlmsg_type = GENL_ID_CTRL; nlh->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK; nlh->nlmsg_seq = seq = time(NULL); genl = mnl_nlmsg_put_extra_header(nlh, sizeof(struct genlmsghdr)); genl->cmd = CTRL_CMD_GETFAMILY; genl->version = 1; mnl_attr_put_u32(nlh, CTRL_ATTR_FAMILY_ID, GENL_ID_CTRL); mnl_attr_put_strz(nlh, CTRL_ATTR_FAMILY_NAME, argv[1]); nl = mnl_socket_open(NETLINK_GENERIC); if (nl == NULL) { perror("mnl_socket_open"); exit(EXIT_FAILURE); } if (mnl_socket_bind(nl, 0, MNL_SOCKET_AUTOPID) < 0) { perror("mnl_socket_bind"); exit(EXIT_FAILURE); } portid = mnl_socket_get_portid(nl); if (mnl_socket_sendto(nl, nlh, nlh->nlmsg_len) < 0) { perror("mnl_socket_send"); exit(EXIT_FAILURE); } ret = mnl_socket_recvfrom(nl, buf, sizeof(buf)); while (ret > 0) { ret = mnl_cb_run(buf, ret, seq, portid, data_cb, NULL); if (ret <= 0) break; ret = mnl_socket_recvfrom(nl, buf, sizeof(buf)); } if (ret == -1) { perror("error"); exit(EXIT_FAILURE); } mnl_socket_close(nl); return 0; }
int main(int argc, char *argv[]) { struct mnl_socket *nl; char buf[MNL_SOCKET_BUFFER_SIZE]; struct nlmsghdr *nlh; struct rtmsg *rtm; int ret; unsigned int seq, portid; if (argc != 2) { fprintf(stderr, "Usage: %s <inet|inet6>\n", argv[0]); exit(EXIT_FAILURE); } nlh = mnl_nlmsg_put_header(buf); nlh->nlmsg_type = RTM_GETROUTE; nlh->nlmsg_flags = NLM_F_REQUEST | NLM_F_DUMP; nlh->nlmsg_seq = seq = time(NULL); rtm = mnl_nlmsg_put_extra_header(nlh, sizeof(struct rtmsg)); if (strcmp(argv[1], "inet") == 0) rtm->rtm_family = AF_INET; else if (strcmp(argv[1], "inet6") == 0) rtm->rtm_family = AF_INET6; nl = mnl_socket_open(NETLINK_ROUTE); if (nl == NULL) { perror("mnl_socket_open"); exit(EXIT_FAILURE); } if (mnl_socket_bind(nl, 0, MNL_SOCKET_AUTOPID) < 0) { perror("mnl_socket_bind"); exit(EXIT_FAILURE); } portid = mnl_socket_get_portid(nl); if (mnl_socket_sendto(nl, nlh, nlh->nlmsg_len) < 0) { perror("mnl_socket_send"); exit(EXIT_FAILURE); } ret = mnl_socket_recvfrom(nl, buf, sizeof(buf)); while (ret > 0) { ret = mnl_cb_run(buf, ret, seq, portid, data_cb, NULL); if (ret <= MNL_CB_STOP) break; ret = mnl_socket_recvfrom(nl, buf, sizeof(buf)); } if (ret == -1) { perror("error"); exit(EXIT_FAILURE); } mnl_socket_close(nl); return 0; }
int nftnl_batch_is_supported(void) { struct mnl_socket *nl; struct mnl_nlmsg_batch *b; char buf[MNL_SOCKET_BUFFER_SIZE]; uint32_t seq = time(NULL), req_seq; int ret; nl = mnl_socket_open(NETLINK_NETFILTER); if (nl == NULL) return -1; if (mnl_socket_bind(nl, 0, MNL_SOCKET_AUTOPID) < 0) return -1; b = mnl_nlmsg_batch_start(buf, sizeof(buf)); nftnl_batch_begin(mnl_nlmsg_batch_current(b), seq++); mnl_nlmsg_batch_next(b); req_seq = seq; nftnl_set_nlmsg_build_hdr(mnl_nlmsg_batch_current(b), NFT_MSG_NEWSET, AF_INET, NLM_F_ACK, seq++); mnl_nlmsg_batch_next(b); nftnl_batch_end(mnl_nlmsg_batch_current(b), seq++); mnl_nlmsg_batch_next(b); ret = mnl_socket_sendto(nl, mnl_nlmsg_batch_head(b), mnl_nlmsg_batch_size(b)); if (ret < 0) goto err; mnl_nlmsg_batch_stop(b); ret = mnl_socket_recvfrom(nl, buf, sizeof(buf)); while (ret > 0) { ret = mnl_cb_run(buf, ret, req_seq, mnl_socket_get_portid(nl), NULL, NULL); if (ret <= 0) break; ret = mnl_socket_recvfrom(nl, buf, sizeof(buf)); } mnl_socket_close(nl); /* We're sending an incomplete message to see if the kernel supports * set messages in batches. EINVAL means that we sent an incomplete * message with missing attributes. The kernel just ignores messages * that we cannot include in the batch. */ return (ret == -1 && errno == EINVAL) ? 1 : 0; err: mnl_nlmsg_batch_stop(b); return -1; }
int main(void) { struct mnl_socket *nl; char buf[MNL_SOCKET_BUFFER_SIZE]; struct nlmsghdr *nlh; struct nfgenmsg *nfh; uint32_t seq, portid; int ret; nl = mnl_socket_open(NETLINK_NETFILTER); if (nl == NULL) { perror("mnl_socket_open"); exit(EXIT_FAILURE); } if (mnl_socket_bind(nl, 0, MNL_SOCKET_AUTOPID) < 0) { perror("mnl_socket_bind"); exit(EXIT_FAILURE); } nlh = mnl_nlmsg_put_header(buf); nlh->nlmsg_type = (NFNL_SUBSYS_CTNETLINK << 8) | IPCTNL_MSG_CT_GET; nlh->nlmsg_flags = NLM_F_REQUEST|NLM_F_DUMP; nlh->nlmsg_seq = seq = time(NULL); nfh = mnl_nlmsg_put_extra_header(nlh, sizeof(struct nfgenmsg)); nfh->nfgen_family = AF_INET; nfh->version = NFNETLINK_V0; nfh->res_id = 0; ret = mnl_socket_sendto(nl, nlh, nlh->nlmsg_len); if (ret == -1) { perror("mnl_socket_sendto"); exit(EXIT_FAILURE); } portid = mnl_socket_get_portid(nl); while (1) { ret = mnl_socket_recvfrom(nl, buf, sizeof(buf)); if (ret == -1) { perror("mnl_socket_recvfrom"); exit(EXIT_FAILURE); } ret = mnl_cb_run(buf, ret, seq, portid, data_cb, NULL); if (ret == -1) { perror("mnl_cb_run"); exit(EXIT_FAILURE); } else if (ret <= MNL_CB_STOP) break; } mnl_socket_close(nl); return 0; }
int main(int argc, char *argv[]) { char buf[getpagesize()]; struct nlmsghdr *nlh; struct genlmsghdr *genl; struct mnl_socket *nl; int ret; unsigned int seq, oper, portid; if (argc != 2) { printf("%s <genetlink family ID>\n", argv[0]); exit(EXIT_FAILURE); } nlh = mnl_nlmsg_put_header(buf); nlh->nlmsg_type = atoi(argv[1]); nlh->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK; nlh->nlmsg_seq = seq = time(NULL); genl = mnl_nlmsg_put_extra_header(nlh, sizeof(struct genlmsghdr)); genl->cmd = NLEX_CMD_GET; nl = mnl_socket_open(NETLINK_GENERIC); if (nl == NULL) { perror("mnl_socket_open"); exit(EXIT_FAILURE); } ret = mnl_socket_bind(nl, 0, MNL_SOCKET_AUTOPID); if (ret == -1) { perror("mnl_socket_bind"); exit(EXIT_FAILURE); } portid = mnl_socket_get_portid(nl); ret = mnl_socket_sendto(nl, nlh, nlh->nlmsg_len); if (ret == -1) { perror("mnl_socket_send"); exit(EXIT_FAILURE); } ret = mnl_socket_recvfrom(nl, buf, sizeof(buf)); while (ret == -1) { perror("mnl_socket_recvfrom"); exit(EXIT_FAILURE); } ret = mnl_cb_run(buf, ret, seq, portid, cb, NULL); if (ret == -1) { perror("mnl_cb_run"); exit(EXIT_FAILURE); } mnl_socket_close(nl); printf("done\n"); return 0; }
//Initialize the Linux-specific part of the context. All is related to //libmnl/netfilter struct neat_ctx *nt_linux_init_ctx(struct neat_ctx *ctx) { //TODO: Consider allocator function if ((ctx->mnl_rcv_buf = calloc(1, MNL_SOCKET_BUFFER_SIZE)) == NULL) { nt_log(ctx, NEAT_LOG_ERROR, "Failed to allocate netlink buffer", __func__); return NULL; } //Configure netlink and start requesting addresses if ((ctx->mnl_sock = mnl_socket_open(NETLINK_ROUTE)) == NULL) { nt_log(ctx, NEAT_LOG_ERROR, "Failed to allocate netlink socket", __func__); return NULL; } if (mnl_socket_bind(ctx->mnl_sock, (1 << (RTNLGRP_IPV4_IFADDR - 1)) | (1 << (RTNLGRP_IPV6_IFADDR - 1)), 0)) { nt_log(ctx, NEAT_LOG_ERROR, "Failed to bind netlink socket", __func__); return NULL; } //We need to build a list of all available source addresses as soon as //possible. It is started here if (neat_linux_request_addrs(ctx->mnl_sock) <= 0) { nt_log(ctx, NEAT_LOG_ERROR, "Failed to request addresses", __func__); return NULL; } //Add socket to event loop if (uv_udp_init(ctx->loop, &(ctx->uv_nl_handle))) { nt_log(ctx, NEAT_LOG_ERROR, "Failed to initialize uv UDP handle", __func__); return NULL; } //TODO: We could use offsetof, but libuv has a pointer so ... ctx->uv_nl_handle.data = ctx; if (uv_udp_open(&(ctx->uv_nl_handle), mnl_socket_get_fd(ctx->mnl_sock))) { nt_log(ctx, NEAT_LOG_ERROR, "Could not add netlink socket to uv", __func__); return NULL; } if (uv_udp_recv_start(&(ctx->uv_nl_handle), neat_linux_nl_alloc, nt_linux_nl_recv)) { nt_log(ctx, NEAT_LOG_ERROR, "Could not start receiving netlink packets", __func__); return NULL; } ctx->cleanup = nt_linux_cleanup; #ifdef MPTCP_SUPPORT linux_read_sys_mptcp_enabled(ctx); #endif // MPTCP_SUPPORT //Configure netlink socket, add to event loop and start dumping return ctx; }
/* method: bind */ static int mnl_socket__bind__meth(lua_State *L) { mnl_socket * this_idx1; unsigned int groups_idx2; pid_t pid_idx3; int rc_mnl_socket_bind_idx1 = 0; this_idx1 = obj_type_mnl_socket_check(L,1); groups_idx2 = luaL_checkinteger(L,2); pid_idx3 = luaL_checkinteger(L,3); rc_mnl_socket_bind_idx1 = mnl_socket_bind(this_idx1, groups_idx2, pid_idx3); lua_pushinteger(L, rc_mnl_socket_bind_idx1); return 1; }
int main(int argc, char *argv[]) { struct mnl_socket *nl; char buf[MNL_SOCKET_BUFFER_SIZE]; int ret, type; switch (argc) { case 1: type = NFT_OUTPUT_DEFAULT; break; case 2: if (strcmp(argv[1], "xml") == 0) { type = NFT_OUTPUT_XML; } else if (strcmp(argv[1], "json") == 0) { type = NFT_OUTPUT_JSON; } else if (strcmp(argv[1], "default") == 0) { type = NFT_OUTPUT_DEFAULT; } else { fprintf(stderr, "unknown format type `%s'\n", argv[1]); return EXIT_FAILURE; } break; default: fprintf(stderr, "%s [<default|xml|json>]\n", argv[0]); return EXIT_FAILURE; } nl = mnl_socket_open(NETLINK_NETFILTER); if (nl == NULL) { perror("mnl_socket_open"); exit(EXIT_FAILURE); } if (mnl_socket_bind(nl, (1 << (NFNLGRP_NFTABLES-1)), MNL_SOCKET_AUTOPID) < 0) { perror("mnl_socket_bind"); exit(EXIT_FAILURE); } ret = mnl_socket_recvfrom(nl, buf, sizeof(buf)); while (ret > 0) { ret = mnl_cb_run(buf, ret, 0, 0, events_cb, &type); if (ret <= 0) break; ret = mnl_socket_recvfrom(nl, buf, sizeof(buf)); } if (ret == -1) { perror("error"); exit(EXIT_FAILURE); } mnl_socket_close(nl); return EXIT_SUCCESS; }
//Initialize the Linux-specific part of the context. All is related to //libmnl/netfilter struct neat_ctx *neat_linux_init_ctx(struct neat_ctx *nc) { //TODO: Consider allocator function if ((nc->mnl_rcv_buf = calloc(MNL_SOCKET_BUFFER_SIZE, 1)) == NULL) { fprintf(stderr, "Failed to allocate netlink buffer\n"); return NULL; } //Configure netlink and start requesting addresses if ((nc->mnl_sock = mnl_socket_open(NETLINK_ROUTE)) == NULL) { fprintf(stderr, "Failed to allocate netlink socket\n"); return NULL; } if (mnl_socket_bind(nc->mnl_sock, (1 << (RTNLGRP_IPV4_IFADDR - 1)) | (1 << (RTNLGRP_IPV6_IFADDR - 1)), 0)) { fprintf(stderr, "Failed to bind netlink socket\n"); return NULL; } //We need to build a list of all available source addresses as soon as //possible. It is started here if (neat_linux_request_addrs(nc->mnl_sock) <= 0) { fprintf(stderr, "Failed to request addresses\n"); return NULL; } //Add socket to event loop if (uv_udp_init(nc->loop, &(nc->uv_nl_handle))) { fprintf(stderr, "Failed to initialize uv UDP handle\n"); return NULL; } //TODO: We could use offsetof, but libuv has a pointer so ... nc->uv_nl_handle.data = nc; if (uv_udp_open(&(nc->uv_nl_handle), mnl_socket_get_fd(nc->mnl_sock))) { fprintf(stderr, "Could not add netlink socket to uv\n"); return NULL; } if (uv_udp_recv_start(&(nc->uv_nl_handle), neat_linux_nl_alloc, neat_linux_nl_recv)) { fprintf(stderr, "Could not start receiving netlink packets\n"); return NULL; } nc->cleanup = neat_linux_cleanup; //Configure netlink socket, add to event loop and start dumping return nc; }
int main(void) { struct mnl_socket *nl; char buf[MNL_SOCKET_BUFFER_SIZE]; struct nlmsghdr *nlh; struct rtgenmsg *rt; int ret; unsigned int seq, portid; nlh = mnl_nlmsg_put_header(buf); nlh->nlmsg_type = RTM_GETLINK; nlh->nlmsg_flags = NLM_F_REQUEST | NLM_F_DUMP; nlh->nlmsg_seq = seq = time(NULL); rt = mnl_nlmsg_put_extra_header(nlh, sizeof(struct rtgenmsg)); rt->rtgen_family = AF_PACKET; nl = mnl_socket_open(NETLINK_ROUTE); if (nl == NULL) { perror("mnl_socket_open"); exit(EXIT_FAILURE); } if (mnl_socket_bind(nl, 0, MNL_SOCKET_AUTOPID) < 0) { perror("mnl_socket_bind"); exit(EXIT_FAILURE); } portid = mnl_socket_get_portid(nl); if (mnl_socket_sendto(nl, nlh, nlh->nlmsg_len) < 0) { perror("mnl_socket_send"); exit(EXIT_FAILURE); } ret = mnl_socket_recvfrom(nl, buf, sizeof(buf)); while (ret > 0) { ret = mnl_cb_run(buf, ret, seq, portid, data_cb, NULL); if (ret <= MNL_CB_STOP) break; ret = mnl_socket_recvfrom(nl, buf, sizeof(buf)); } if (ret == -1) { perror("error"); exit(EXIT_FAILURE); } mnl_socket_close(nl); return 0; }
struct mnl_socket *genl_socket_open(void) { struct mnl_socket *nl; nl = mnl_socket_open(NETLINK_GENERIC); if (nl == NULL) { perror("mnl_socket_open"); return NULL; } if (mnl_socket_bind(nl, 0, MNL_SOCKET_AUTOPID) < 0) { perror("mnl_socket_bind"); return NULL; } return nl; }
int main(void) { char buf[getpagesize()]; struct nlmsghdr *nlh; struct mnl_socket *nl; int ret; unsigned int seq, portid; nlh = mnl_nlmsg_put_header(buf); nlh->nlmsg_type = NLEX_MSG_UPD; nlh->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK; nlh->nlmsg_seq = seq = time(NULL); nlh->nlmsg_pid = getpid(); mnl_attr_put_u32(nlh, NLE_MYVAR, 31337); nl = mnl_socket_open(NETLINK_EXAMPLE); if (nl == NULL) { perror("mnl_socket_open"); exit(EXIT_FAILURE); } if (mnl_socket_bind(nl, 0, MNL_SOCKET_AUTOPID) < 0) { perror("mnl_socket_bind"); exit(EXIT_FAILURE); } portid = mnl_socket_get_portid(nl); if (mnl_socket_sendto(nl, nlh, nlh->nlmsg_len) < 0) { perror("mnl_socket_sendto"); exit(EXIT_FAILURE); } ret = mnl_cb_run(buf, ret, seq, portid, NULL, NULL); if (ret == -1) { perror("mnl_cb_callback"); exit(EXIT_FAILURE); } mnl_socket_close(nl); return 0; }
int main(int argc, char ** argv) { struct mnl_socket * nl; char buf[MNL_SOCKET_BUFFER_SIZE]; int ret; program = argv[0]; printf("%s: %s v%s (compiled: %s)\n", argv[0], PROGNAME, VERSION, DATE); if(!notify_init("Netlink-Notification")) { fprintf(stderr, "%s: Can't create notify.\n", argv[0]); exit(EXIT_FAILURE); } nl = mnl_socket_open(NETLINK_ROUTE); if (!nl) { fprintf(stderr, "%s: Can't create netlink socket.\n", argv[0]); exit(EXIT_FAILURE); } if (mnl_socket_bind(nl, RTMGRP_LINK, MNL_SOCKET_AUTOPID) < 0) { fprintf(stderr, "%s: Can't bind netlink socket.\n", argv[0]); exit(EXIT_FAILURE); } ret = mnl_socket_recvfrom(nl, buf, sizeof(buf)); while (ret > 0) { ret = mnl_cb_run(buf, ret, 0, 0, data_cb, NULL); if (ret <= 0) break; ret = mnl_socket_recvfrom(nl, buf, sizeof(buf)); } if (ret == -1) { fprintf(stderr, "%s: An error occured reading from netlink socket.\n", argv[0]); exit(EXIT_FAILURE); } mnl_socket_close(nl); return EXIT_SUCCESS; }
static int socket_open_and_bind(struct mnl_socket **n) { struct mnl_socket *nl = NULL; int err; nl = mnl_socket_open(NETLINK_NETFILTER); if (!nl) return -errno; err = mnl_socket_bind(nl, 1 << (NFNLGRP_NFTABLES-1), MNL_SOCKET_AUTOPID); if (err < 0) { err = errno; mnl_socket_close(nl); return -err; } *n = nl; return 0; }
int main(int argc, char *argv[]) { struct mnl_socket *nl; char buf[MNL_SOCKET_BUFFER_SIZE]; struct nlmsghdr *nlh; uint32_t portid, seq, family, data; struct nft_set *s; struct nft_set_elem *e; int ret; if (argc != 4) { fprintf(stderr, "%s <family> <table> <set>\n", argv[0]); exit(EXIT_FAILURE); } s = nft_set_alloc(); if (s == NULL) { perror("OOM"); exit(EXIT_FAILURE); } seq = time(NULL); if (strcmp(argv[1], "ip") == 0) family = NFPROTO_IPV4; else if (strcmp(argv[1], "ip6") == 0) family = NFPROTO_IPV6; else if (strcmp(argv[1], "bridge") == 0) family = NFPROTO_BRIDGE; else if (strcmp(argv[1], "arp") == 0) family = NFPROTO_ARP; else { fprintf(stderr, "Unknown family: ip, ip6, bridge, arp\n"); exit(EXIT_FAILURE); } nft_set_attr_set(s, NFT_SET_ATTR_TABLE, argv[2]); nft_set_attr_set(s, NFT_SET_ATTR_NAME, argv[3]); /* Add to dummy elements to set */ e = nft_set_elem_alloc(); if (e == NULL) { perror("OOM"); exit(EXIT_FAILURE); } data = 0x1; nft_set_elem_attr_set(e, NFT_SET_ELEM_ATTR_KEY, &data, sizeof(data)); nft_set_elem_add(s, e); e = nft_set_elem_alloc(); if (e == NULL) { perror("OOM"); exit(EXIT_FAILURE); } data = 0x2; nft_set_elem_attr_set(e, NFT_SET_ELEM_ATTR_KEY, &data, sizeof(data)); nft_set_elem_add(s, e); nlh = nft_set_nlmsg_build_hdr(buf, NFT_MSG_NEWSETELEM, family, NLM_F_CREATE|NLM_F_EXCL|NLM_F_ACK, seq); nft_set_elems_nlmsg_build_payload(nlh, s); nft_set_free(s); nl = mnl_socket_open(NETLINK_NETFILTER); if (nl == NULL) { perror("mnl_socket_open"); exit(EXIT_FAILURE); } if (mnl_socket_bind(nl, 0, MNL_SOCKET_AUTOPID) < 0) { perror("mnl_socket_bind"); exit(EXIT_FAILURE); } portid = mnl_socket_get_portid(nl); if (mnl_socket_sendto(nl, nlh, nlh->nlmsg_len) < 0) { perror("mnl_socket_send"); exit(EXIT_FAILURE); } ret = mnl_socket_recvfrom(nl, buf, sizeof(buf)); while (ret > 0) { ret = mnl_cb_run(buf, ret, seq, portid, NULL, NULL); if (ret <= 0) break; ret = mnl_socket_recvfrom(nl, buf, sizeof(buf)); } if (ret == -1) { perror("error"); exit(EXIT_FAILURE); } mnl_socket_close(nl); return EXIT_SUCCESS; }
int main(int argc, char *argv[]) { struct mnl_socket *nl; struct nftnl_rule *r; struct nlmsghdr *nlh; struct mnl_nlmsg_batch *batch; uint8_t family; char buf[MNL_SOCKET_BUFFER_SIZE]; uint32_t seq = time(NULL); int ret; if (argc < 4 || argc > 5) { fprintf(stderr, "Usage: %s <family> <table> <chain>\n", argv[0]); exit(EXIT_FAILURE); } if (strcmp(argv[1], "ip") == 0) family = NFPROTO_IPV4; else if (strcmp(argv[1], "ip6") == 0) family = NFPROTO_IPV6; else { fprintf(stderr, "Unknown family: ip, ip6\n"); exit(EXIT_FAILURE); } if (argc != 5) r = setup_rule(family, argv[2], argv[3], NULL); else r = setup_rule(family, argv[2], argv[3], argv[4]); nl = mnl_socket_open(NETLINK_NETFILTER); if (nl == NULL) { perror("mnl_socket_open"); exit(EXIT_FAILURE); } if (mnl_socket_bind(nl, 0, MNL_SOCKET_AUTOPID) < 0) { perror("mnl_socket_bind"); exit(EXIT_FAILURE); } batch = mnl_nlmsg_batch_start(buf, sizeof(buf)); nftnl_mnl_batch_put(mnl_nlmsg_batch_current(batch), NFNL_MSG_BATCH_BEGIN, seq++); mnl_nlmsg_batch_next(batch); nlh = nftnl_rule_nlmsg_build_hdr(mnl_nlmsg_batch_current(batch), NFT_MSG_NEWRULE, nftnl_rule_get_u32(r, NFTNL_RULE_FAMILY), NLM_F_APPEND|NLM_F_CREATE|NLM_F_ACK, seq++); nftnl_rule_nlmsg_build_payload(nlh, r); nftnl_rule_free(r); mnl_nlmsg_batch_next(batch); nftnl_mnl_batch_put(mnl_nlmsg_batch_current(batch), NFNL_MSG_BATCH_END, seq++); mnl_nlmsg_batch_next(batch); ret = mnl_socket_sendto(nl, mnl_nlmsg_batch_head(batch), mnl_nlmsg_batch_size(batch)); if (ret == -1) { perror("mnl_socket_sendto"); exit(EXIT_FAILURE); } mnl_nlmsg_batch_stop(batch); ret = mnl_socket_recvfrom(nl, buf, sizeof(buf)); if (ret == -1) { perror("mnl_socket_recvfrom"); exit(EXIT_FAILURE); } ret = mnl_cb_run(buf, ret, 0, mnl_socket_get_portid(nl), NULL, NULL); if (ret < 0) { perror("mnl_cb_run"); exit(EXIT_FAILURE); } mnl_socket_close(nl); return EXIT_SUCCESS; }
int main(int argc, char *argv[]) { struct mnl_socket *nl; char buf[MNL_SOCKET_BUFFER_SIZE]; struct nlmsghdr *nlh; int ret; unsigned int portid, queue_num; if (argc != 2) { printf("Usage: %s [queue_num]\n", argv[0]); exit(EXIT_FAILURE); } queue_num = atoi(argv[1]); nl = mnl_socket_open(NETLINK_NETFILTER); if (nl == NULL) { perror("mnl_socket_open"); exit(EXIT_FAILURE); } if (mnl_socket_bind(nl, 0, MNL_SOCKET_AUTOPID) < 0) { perror("mnl_socket_bind"); exit(EXIT_FAILURE); } portid = mnl_socket_get_portid(nl); nlh = nfq_build_cfg_pf_request(buf, NFQNL_CFG_CMD_PF_UNBIND); if (mnl_socket_sendto(nl, nlh, nlh->nlmsg_len) < 0) { perror("mnl_socket_send"); exit(EXIT_FAILURE); } nlh = nfq_build_cfg_pf_request(buf, NFQNL_CFG_CMD_PF_BIND); if (mnl_socket_sendto(nl, nlh, nlh->nlmsg_len) < 0) { perror("mnl_socket_send"); exit(EXIT_FAILURE); } nlh = nfq_build_cfg_request(buf, NFQNL_CFG_CMD_BIND, queue_num); if (mnl_socket_sendto(nl, nlh, nlh->nlmsg_len) < 0) { perror("mnl_socket_send"); exit(EXIT_FAILURE); } nlh = nfq_build_cfg_params(buf, NFQNL_COPY_PACKET, 0xFFFF, queue_num); if (mnl_socket_sendto(nl, nlh, nlh->nlmsg_len) < 0) { perror("mnl_socket_send"); exit(EXIT_FAILURE); } ret = mnl_socket_recvfrom(nl, buf, sizeof(buf)); if (ret == -1) { perror("mnl_socket_recvfrom"); exit(EXIT_FAILURE); } while (ret > 0) { uint32_t id; ret = mnl_cb_run(buf, ret, 0, portid, queue_cb, NULL); if (ret < 0){ perror("mnl_cb_run"); exit(EXIT_FAILURE); } id = ret - MNL_CB_OK; nlh = nfq_build_verdict(buf, id, queue_num, NF_ACCEPT); if (mnl_socket_sendto(nl, nlh, nlh->nlmsg_len) < 0) { perror("mnl_socket_send"); exit(EXIT_FAILURE); } ret = mnl_socket_recvfrom(nl, buf, sizeof(buf)); if (ret == -1) { perror("mnl_socket_recvfrom"); exit(EXIT_FAILURE); } } mnl_socket_close(nl); return 0; }
int main(int argc, char *argv[]) { if (argc <= 3) { printf("Usage: %s iface destination cidr [gateway]\n", argv[0]); printf("Example: %s eth0 10.0.1.12 32 10.0.1.11\n", argv[0]); exit(EXIT_FAILURE); } int iface; iface = if_nametoindex(argv[1]); if (iface == 0) { printf("Bad interface name\n"); exit(EXIT_FAILURE); } in_addr_t dst; if (!inet_pton(AF_INET, argv[2], &dst)) { printf("Bad destination\n"); exit(EXIT_FAILURE); } uint32_t mask; if (sscanf(argv[3], "%u", &mask) == 0) { printf("Bad CIDR\n"); exit(EXIT_FAILURE); } in_addr_t gw; if (argc >= 5 && !inet_pton(AF_INET, argv[4], &gw)) { printf("Bad gateway\n"); exit(EXIT_FAILURE); } struct mnl_socket *nl; char buf[MNL_SOCKET_BUFFER_SIZE]; struct nlmsghdr *nlh; struct rtmsg *rtm; nlh = mnl_nlmsg_put_header(buf); nlh->nlmsg_type = RTM_NEWROUTE; nlh->nlmsg_flags = NLM_F_REQUEST | NLM_F_CREATE; nlh->nlmsg_seq = time(NULL); rtm = mnl_nlmsg_put_extra_header(nlh, sizeof(struct rtmsg)); rtm->rtm_family = AF_INET; rtm->rtm_dst_len = mask; rtm->rtm_src_len = 0; rtm->rtm_tos = 0; rtm->rtm_protocol = RTPROT_BOOT; rtm->rtm_table = RT_TABLE_MAIN; rtm->rtm_type = RTN_UNICAST; /* is there any gateway? */ rtm->rtm_scope = (argc == 4) ? RT_SCOPE_LINK : RT_SCOPE_UNIVERSE; rtm->rtm_flags = 0; mnl_attr_put_u32(nlh, RTA_DST, dst); mnl_attr_put_u32(nlh, RTA_OIF, iface); if (argc >= 5) mnl_attr_put_u32(nlh, RTA_GATEWAY, gw); nl = mnl_socket_open(NETLINK_ROUTE); if (nl == NULL) { perror("mnl_socket_open"); exit(EXIT_FAILURE); } if (mnl_socket_bind(nl, 0, MNL_SOCKET_AUTOPID) < 0) { perror("mnl_socket_bind"); exit(EXIT_FAILURE); } if (mnl_socket_sendto(nl, nlh, nlh->nlmsg_len) < 0) { perror("mnl_socket_send"); exit(EXIT_FAILURE); } mnl_socket_close(nl); return 0; }
static void send_batch(struct mnl_socket *nl, struct mnl_nlmsg_batch *b, int portid) { int ret, fd = mnl_socket_get_fd(nl); size_t len = mnl_nlmsg_batch_size(b); char rcv_buf[MNL_SOCKET_BUFFER_SIZE]; ret = mnl_socket_sendto(nl, mnl_nlmsg_batch_head(b), len); if (ret == -1) { perror("mnl_socket_recvfrom"); exit(EXIT_FAILURE); } /* receive and digest all the acknowledgments from the kernel. */ struct timeval tv = { .tv_sec = 0, .tv_usec = 0 }; fd_set readfds; FD_ZERO(&readfds); FD_SET(fd, &readfds); ret = select(fd+1, &readfds, NULL, NULL, &tv); if (ret == -1) { perror("select"); exit(EXIT_FAILURE); } while (ret > 0 && FD_ISSET(fd, &readfds)) { ret = mnl_socket_recvfrom(nl, rcv_buf, sizeof(rcv_buf)); if (ret == -1) { perror("mnl_socket_recvfrom"); exit(EXIT_FAILURE); } ret = mnl_cb_run2(rcv_buf, ret, 0, portid, NULL, NULL, cb_ctl_array, MNL_ARRAY_SIZE(cb_ctl_array)); if (ret == -1) { perror("mnl_cb_run"); exit(EXIT_FAILURE); } ret = select(fd+1, &readfds, NULL, NULL, &tv); if (ret == -1) { perror("select"); exit(EXIT_FAILURE); } FD_ZERO(&readfds); FD_SET(fd, &readfds); } } int main(void) { struct mnl_socket *nl; char snd_buf[MNL_SOCKET_BUFFER_SIZE*2]; struct mnl_nlmsg_batch *b; int j; unsigned int seq, portid; uint16_t i; nl = mnl_socket_open(NETLINK_NETFILTER); if (nl == NULL) { perror("mnl_socket_open"); exit(EXIT_FAILURE); } if (mnl_socket_bind(nl, 0, MNL_SOCKET_AUTOPID) < 0) { perror("mnl_socket_bind"); exit(EXIT_FAILURE); } portid = mnl_socket_get_portid(nl); /* The buffer that we use to batch messages is MNL_SOCKET_BUFFER_SIZE * multiplied by 2 bytes long, but we limit the batch to half of it * since the last message that does not fit the batch goes over the * upper boundary, if you break this rule, expect memory corruptions. */ b = mnl_nlmsg_batch_start(snd_buf, MNL_SOCKET_BUFFER_SIZE); if (b == NULL) { perror("mnl_nlmsg_batch_start"); exit(EXIT_FAILURE); } seq = time(NULL); for (i=1024, j=0; i<65535; i++, j++) { put_msg(mnl_nlmsg_batch_current(b), i, seq+j); /* is there room for more messages in this batch? * if so, continue. */ if (mnl_nlmsg_batch_next(b)) continue; send_batch(nl, b, portid); /* this moves the last message that did not fit into the * batch to the head of it. */ mnl_nlmsg_batch_reset(b); } /* check if there is any message in the batch not sent yet. */ if (!mnl_nlmsg_batch_is_empty(b)) send_batch(nl, b, portid); mnl_nlmsg_batch_stop(b); mnl_socket_close(nl); return 0; }
int main(int argc, char *argv[]) { struct mnl_socket *nl; char buf[MNL_SOCKET_BUFFER_SIZE]; struct nlmsghdr *nlh; struct mnl_nlmsg_batch *batch; uint32_t portid, seq; struct nft_rule *r = NULL; int ret, family; if (argc < 4 || argc > 5) { fprintf(stderr, "Usage: %s <family> <table> <chain> [<handle>]\n", argv[0]); exit(EXIT_FAILURE); } r = nft_rule_alloc(); if (r == NULL) { perror("OOM"); exit(EXIT_FAILURE); } if (strcmp(argv[1], "ip") == 0) family = NFPROTO_IPV4; else if (strcmp(argv[1], "ip6") == 0) family = NFPROTO_IPV6; else if (strcmp(argv[1], "bridge") == 0) family = NFPROTO_BRIDGE; else if (strcmp(argv[1], "arp") == 0) family = NFPROTO_ARP; else { fprintf(stderr, "Unknown family: ip, ip6, bridge, arp\n"); exit(EXIT_FAILURE); } seq = time(NULL); nft_rule_attr_set(r, NFT_RULE_ATTR_TABLE, argv[2]); nft_rule_attr_set(r, NFT_RULE_ATTR_CHAIN, argv[3]); /* If no handle is specified, delete all rules in the chain */ if (argc == 5) nft_rule_attr_set_u64(r, NFT_RULE_ATTR_HANDLE, atoi(argv[4])); batch = mnl_nlmsg_batch_start(buf, sizeof(buf)); nft_mnl_batch_put(mnl_nlmsg_batch_current(batch), NFNL_MSG_BATCH_BEGIN, seq++); mnl_nlmsg_batch_next(batch); nlh = nft_rule_nlmsg_build_hdr(mnl_nlmsg_batch_current(batch), NFT_MSG_DELRULE, family, NLM_F_ACK, seq++); nft_rule_nlmsg_build_payload(nlh, r); nft_rule_free(r); mnl_nlmsg_batch_next(batch); nft_mnl_batch_put(mnl_nlmsg_batch_current(batch), NFNL_MSG_BATCH_END, seq++); mnl_nlmsg_batch_next(batch); nl = mnl_socket_open(NETLINK_NETFILTER); if (nl == NULL) { perror("mnl_socket_open"); exit(EXIT_FAILURE); } if (mnl_socket_bind(nl, 0, MNL_SOCKET_AUTOPID) < 0) { perror("mnl_socket_bind"); exit(EXIT_FAILURE); } portid = mnl_socket_get_portid(nl); if (mnl_socket_sendto(nl, mnl_nlmsg_batch_head(batch), mnl_nlmsg_batch_size(batch)) < 0) { perror("mnl_socket_send"); exit(EXIT_FAILURE); } mnl_nlmsg_batch_stop(batch); ret = mnl_socket_recvfrom(nl, buf, sizeof(buf)); while (ret > 0) { ret = mnl_cb_run(buf, ret, 0, portid, NULL, NULL); if (ret <= 0) break; ret = mnl_socket_recvfrom(nl, buf, sizeof(buf)); } if (ret == -1) { perror("error"); exit(EXIT_FAILURE); } mnl_socket_close(nl); return EXIT_SUCCESS; }
int main(int argc, char *argv[]) { char buf[MNL_SOCKET_BUFFER_SIZE]; struct nlmsghdr *nlh; int ret; unsigned int portid, qnum; atexit(cleanup); if (argc != 2) { printf("Usage: %s [queue_num]\n", argv[0]); exit(EXIT_FAILURE); } qnum = atoi(argv[1]); nl = mnl_socket_open(NETLINK_NETFILTER); if (nl == NULL) { perror("mnl_socket_open"); exit(EXIT_FAILURE); } if (mnl_socket_bind(nl, 0, MNL_SOCKET_AUTOPID) < 0) { perror("mnl_socket_bind"); exit(EXIT_FAILURE); } portid = mnl_socket_get_portid(nl); nlh = nflog_build_cfg_pf_request(buf, NFULNL_CFG_CMD_PF_UNBIND); if (mnl_socket_sendto(nl, nlh, nlh->nlmsg_len) < 0) { perror("mnl_socket_send"); exit(EXIT_FAILURE); } nlh = nflog_build_cfg_pf_request(buf, NFULNL_CFG_CMD_PF_BIND); if (mnl_socket_sendto(nl, nlh, nlh->nlmsg_len) < 0) { perror("mnl_socket_send"); exit(EXIT_FAILURE); } nlh = nflog_build_cfg_request(buf, NFULNL_CFG_CMD_BIND, qnum); if (mnl_socket_sendto(nl, nlh, nlh->nlmsg_len) < 0) { perror("mnl_socket_send"); exit(EXIT_FAILURE); } nlh = nflog_build_cfg_params(buf, NFULNL_COPY_PACKET, 0xFFFF, qnum); if (mnl_socket_sendto(nl, nlh, nlh->nlmsg_len) < 0) { perror("mnl_socket_send"); exit(EXIT_FAILURE); } ret = mnl_socket_recvfrom(nl, buf, sizeof(buf)); if (ret == -1) { if(errno == ENOSPC || errno == ENOBUFS) { /* ignore these (hopefully) recoverable errors */ } else { perror("mnl_socket_recvfrom"); exit(EXIT_FAILURE); } } while (1) { if (ret == -1) { /* reset ret and skip mnl_cb_run if previous recvfrom had an error */ ret = 0; } else { ret = mnl_cb_run(buf, ret, 0, portid, log_cb, NULL); if (ret < 0) { perror("mnl_cb_run"); exit(EXIT_FAILURE); } } ret = mnl_socket_recvfrom(nl, buf, sizeof(buf)); if (ret == -1) { if (errno == ENOSPC || errno == ENOBUFS) { /* ignore these (hopefully) recoverable errors */ continue; } else { perror("mnl_socket_recvfrom"); exit(EXIT_FAILURE); } } } return 0; }
void *nfacct_main(void *ptr) { if(ptr) { ; } info("NFACCT thread created with task id %d", gettid()); if(pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, NULL) != 0) error("nfacct.plugin: Cannot set pthread cancel type to DEFERRED."); if(pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL) != 0) error("nfacct.plugin: Cannot set pthread cancel state to ENABLE."); char buf[MNL_SOCKET_BUFFER_SIZE]; struct mnl_socket *nl = NULL; struct nlmsghdr *nlh = NULL; unsigned int seq = 0, portid = 0; seq = time(NULL) - 1; nl = mnl_socket_open(NETLINK_NETFILTER); if(!nl) { error("nfacct.plugin: mnl_socket_open() failed"); pthread_exit(NULL); return NULL; } if(mnl_socket_bind(nl, 0, MNL_SOCKET_AUTOPID) < 0) { mnl_socket_close(nl); error("nfacct.plugin: mnl_socket_bind() failed"); pthread_exit(NULL); return NULL; } portid = mnl_socket_get_portid(nl); // ------------------------------------------------------------------------ struct timeval last, now; unsigned long long usec = 0, susec = 0; RRDSET *st = NULL; gettimeofday(&last, NULL); // ------------------------------------------------------------------------ while(1) { if(unlikely(netdata_exit)) break; seq++; nlh = nfacct_nlmsg_build_hdr(buf, NFNL_MSG_ACCT_GET, NLM_F_DUMP, seq); if(!nlh) { mnl_socket_close(nl); error("nfacct.plugin: nfacct_nlmsg_build_hdr() failed"); pthread_exit(NULL); return NULL; } if(mnl_socket_sendto(nl, nlh, nlh->nlmsg_len) < 0) { error("nfacct.plugin: mnl_socket_send"); pthread_exit(NULL); return NULL; } if(nfacct_list) nfacct_list->len = 0; int ret; while((ret = mnl_socket_recvfrom(nl, buf, sizeof(buf))) > 0) { if((ret = mnl_cb_run(buf, ret, seq, portid, nfacct_callback, NULL)) <= 0) break; } if (ret == -1) { error("nfacct.plugin: error communicating with kernel."); pthread_exit(NULL); return NULL; } // -------------------------------------------------------------------- gettimeofday(&now, NULL); usec = usecdiff(&now, &last) - susec; debug(D_NFACCT_LOOP, "nfacct.plugin: last loop took %llu usec (worked for %llu, sleeped for %llu).", usec + susec, usec, susec); if(usec < (rrd_update_every * 1000000ULL / 2ULL)) susec = (rrd_update_every * 1000000ULL) - usec; else susec = rrd_update_every * 1000000ULL / 2ULL; // -------------------------------------------------------------------- if(nfacct_list && nfacct_list->len) { int i; st = rrdset_find_bytype("netfilter", "nfacct_packets"); if(!st) { st = rrdset_create("netfilter", "nfacct_packets", NULL, "nfacct", NULL, "Netfilter Accounting Packets", "packets/s", 1006, rrd_update_every, RRDSET_TYPE_STACKED); for(i = 0; i < nfacct_list->len ; i++) rrddim_add(st, nfacct_list->data[i].name, NULL, 1, rrd_update_every, RRDDIM_INCREMENTAL); } else rrdset_next(st); for(i = 0; i < nfacct_list->len ; i++) { RRDDIM *rd = rrddim_find(st, nfacct_list->data[i].name); if(!rd) rd = rrddim_add(st, nfacct_list->data[i].name, NULL, 1, rrd_update_every, RRDDIM_INCREMENTAL); if(rd) rrddim_set_by_pointer(st, rd, nfacct_list->data[i].pkts); } rrdset_done(st); // ---------------------------------------------------------------- st = rrdset_find_bytype("netfilter", "nfacct_bytes"); if(!st) { st = rrdset_create("netfilter", "nfacct_bytes", NULL, "nfacct", NULL, "Netfilter Accounting Bandwidth", "kilobytes/s", 1007, rrd_update_every, RRDSET_TYPE_STACKED); for(i = 0; i < nfacct_list->len ; i++) rrddim_add(st, nfacct_list->data[i].name, NULL, 1, 1000 * rrd_update_every, RRDDIM_INCREMENTAL); } else rrdset_next(st); for(i = 0; i < nfacct_list->len ; i++) { RRDDIM *rd = rrddim_find(st, nfacct_list->data[i].name); if(!rd) rd = rrddim_add(st, nfacct_list->data[i].name, NULL, 1, 1000 * rrd_update_every, RRDDIM_INCREMENTAL); if(rd) rrddim_set_by_pointer(st, rd, nfacct_list->data[i].bytes); } rrdset_done(st); } // -------------------------------------------------------------------- usleep(susec); // copy current to last bcopy(&now, &last, sizeof(struct timeval)); } mnl_socket_close(nl); pthread_exit(NULL); return NULL; }
static int32_t multi_link_event_loop(struct multi_config *mc){ struct multi_link_info *li; pthread_attr_t detach_attr; uint8_t buf[MAX_PIPE_MSG_LEN]; uint8_t mnl_buf[MNL_SOCKET_BUFFER_SIZE]; int32_t retval, numbytes; uint32_t i; int32_t mnl_sock_event, mnl_sock_set, mnl_sock_get; fd_set masterfds, readfds; int fdmax = 0; struct timeval tv; FD_ZERO(&masterfds); FD_ZERO(&readfds); //NETLINK_ROUTE is where I want to hook into the kernel if(!(multi_link_nl_request = mnl_socket_open(NETLINK_ROUTE))){ MULTI_DEBUG_PRINT_SYSLOG(stderr, "Could not create mnl socket (request)\n"); return EXIT_FAILURE; } if(!(multi_link_nl_set = mnl_socket_open(NETLINK_ROUTE))){ MULTI_DEBUG_PRINT_SYSLOG(stderr, "Could not create mnl socket (set)\n"); return EXIT_FAILURE; } if(!(multi_link_nl_event = mnl_socket_open(NETLINK_ROUTE))){ MULTI_DEBUG_PRINT_SYSLOG(stderr, "Could not create mnl socket (event)\n"); return EXIT_FAILURE; } if(mnl_socket_bind(multi_link_nl_request, 0, MNL_SOCKET_AUTOPID) < 0){ MULTI_DEBUG_PRINT_SYSLOG(stderr, "Could not bind mnl event socket\n"); mnl_socket_close(multi_link_nl_event); return EXIT_FAILURE; } if(mnl_socket_bind(multi_link_nl_set, 0, MNL_SOCKET_AUTOPID) < 0){ MULTI_DEBUG_PRINT_SYSLOG(stderr, "Could not bind mnl event socket\n"); mnl_socket_close(multi_link_nl_event); return EXIT_FAILURE; } if(mnl_socket_bind(multi_link_nl_event, 1 << (RTNLGRP_LINK - 1), MNL_SOCKET_AUTOPID) < 0){ MULTI_DEBUG_PRINT_SYSLOG(stderr, "Could not bind mnl event socket\n"); mnl_socket_close(multi_link_nl_event); return EXIT_FAILURE; } if(pipe(multi_link_dhcp_pipes) < 0){ //perror("Pipe failed\n"); MULTI_DEBUG_PRINT_SYSLOG(stderr,"Pipe failed\n"); return EXIT_FAILURE; } /* Find interfaces that are already up, removes info and then reruns * DHCP (need config) */ multi_link_populate_links_list(); /* Check if I have any PPP links. */ //TODO: Give this one a better name since it is not only for PPP any more LIST_FOREACH_CB(&multi_link_links_2, next, multi_link_check_ppp, li, NULL); MULTI_DEBUG_PRINT_SYSLOG(stderr, "Done populating links list!\n"); if(multi_link_flush_links() == EXIT_FAILURE) return EXIT_FAILURE; //Go through already seen interfaces and start DHCP as needed if(multi_link_num_links > 0){ pthread_attr_init(&detach_attr); pthread_attr_setdetachstate(&detach_attr, PTHREAD_CREATE_DETACHED); for(li = multi_link_links_2.lh_first; li != NULL; li = li->next.le_next){ /* Start DHCP */ if(li->state == WAITING_FOR_DHCP){ MULTI_DEBUG_PRINT_SYSLOG(stderr, "Starting DHCP for existing " "interface %s\n", li->dev_name); pthread_create(&(li->dhcp_thread), &detach_attr, multi_dhcp_main, (void *) li); } } } /* Do a scan of the list here to check for links with static IP/PPP */ LIST_FOREACH_CB(&multi_link_links_2, next, multi_link_check_link, li, mc); mnl_sock_event = mnl_socket_get_fd(multi_link_nl_event); mnl_sock_set = mnl_socket_get_fd(multi_link_nl_set); mnl_sock_get = mnl_socket_get_fd(multi_link_nl_request); FD_SET(mnl_sock_event, &masterfds); fdmax = fdmax > mnl_sock_event ? fdmax : mnl_sock_event; FD_SET(mnl_sock_get, &masterfds); fdmax = fdmax > mnl_sock_get ? fdmax : mnl_sock_get; FD_SET(mnl_sock_set, &masterfds); fdmax = fdmax > mnl_sock_set ? fdmax : mnl_sock_set; FD_SET(multi_link_dhcp_pipes[0], &masterfds); fdmax = fdmax > multi_link_dhcp_pipes[0] ? fdmax : multi_link_dhcp_pipes[0]; tv.tv_sec = 5; tv.tv_usec = 0; while(1){ readfds = masterfds; retval = select(fdmax+1, &readfds, NULL, NULL, &tv); if(retval == 0){ //Check for any PPP that is marked as down LIST_FOREACH_CB(&multi_link_links_2, next, multi_link_check_ppp, li, NULL); LIST_FOREACH_CB(&multi_link_links_2, next, multi_link_check_link, li, mc); tv.tv_sec = 5; tv.tv_usec = 0; continue; } //TODO: Rewrite this so I only call the callbacks at the end, not per //message for(i=0; i<=fdmax; i++){ if(FD_ISSET(i, &readfds)){ if (i == mnl_sock_event){ numbytes = mnl_socket_recvfrom(multi_link_nl_event, mnl_buf, sizeof(mnl_buf)); mnl_cb_run(mnl_buf, numbytes, 0, 0, multi_link_parse_netlink, mc); LIST_FOREACH_CB(&multi_link_links_2, next, multi_link_check_link, li, mc); } else if (i == mnl_sock_set){ numbytes = mnl_socket_recvfrom(multi_link_nl_set, mnl_buf, sizeof(mnl_buf)); } else if (i == mnl_sock_get){ numbytes = mnl_socket_recvfrom(multi_link_nl_request, mnl_buf, sizeof(mnl_buf)); } else if (i == multi_link_dhcp_pipes[0]){ numbytes = read(i, buf, MAX_PIPE_MSG_LEN); LIST_FOREACH_CB(&multi_link_links_2, next, multi_link_check_link, li, mc); multi_link_clean_links(); } } } } }
int main(int argc, char *argv[]) { struct mnl_socket *nl; char buf[MNL_SOCKET_BUFFER_SIZE]; struct nlmsghdr *nlh; uint32_t portid, seq, family; uint32_t type = NFT_OUTPUT_DEFAULT; struct nft_set *t = NULL; int ret; if (argc < 4 || argc > 5) { fprintf(stderr, "%s <family> <table> <set> [<json|xml>]\n", argv[0]); return EXIT_FAILURE; } t = nft_set_alloc(); if (t == NULL) { perror("OOM"); exit(EXIT_FAILURE); } seq = time(NULL); if (strcmp(argv[1], "ip") == 0) family = NFPROTO_IPV4; else if (strcmp(argv[1], "ip6") == 0) family = NFPROTO_IPV6; else if (strcmp(argv[1], "bridge") == 0) family = NFPROTO_BRIDGE; else if (strcmp(argv[1], "arp") == 0) family = NFPROTO_ARP; else { fprintf(stderr, "Unknown family: ip, ip6, bridge, arp\n"); exit(EXIT_FAILURE); } if (argc == 5 && strcmp(argv[4], "json") == 0 ) type = NFT_OUTPUT_JSON; else if (argc == 5 && strcmp(argv[4], "xml") == 0) type = NFT_OUTPUT_XML; nlh = nft_set_nlmsg_build_hdr(buf, NFT_MSG_GETSETELEM, family, NLM_F_DUMP|NLM_F_ACK, seq); nft_set_attr_set(t, NFT_SET_ATTR_NAME, argv[3]); nft_set_attr_set(t, NFT_SET_ATTR_TABLE, argv[2]); nft_set_elems_nlmsg_build_payload(nlh, t); nft_set_free(t); nl = mnl_socket_open(NETLINK_NETFILTER); if (nl == NULL) { perror("mnl_socket_open"); exit(EXIT_FAILURE); } if (mnl_socket_bind(nl, 0, MNL_SOCKET_AUTOPID) < 0) { perror("mnl_socket_bind"); exit(EXIT_FAILURE); } portid = mnl_socket_get_portid(nl); if (mnl_socket_sendto(nl, nlh, nlh->nlmsg_len) < 0) { perror("mnl_socket_send"); exit(EXIT_FAILURE); } ret = mnl_socket_recvfrom(nl, buf, sizeof(buf)); while (ret > 0) { ret = mnl_cb_run(buf, ret, seq, portid, set_cb, &type); if (ret <= 0) break; ret = mnl_socket_recvfrom(nl, buf, sizeof(buf)); } if (ret == -1) { perror("error"); exit(EXIT_FAILURE); } mnl_socket_close(nl); return EXIT_SUCCESS; }
int main(int argc, char *argv[]) { struct mnl_socket *nl; char buf[MNL_SOCKET_BUFFER_SIZE]; struct nlmsghdr *nlh; uint32_t portid, seq, set_seq; struct nftnl_set *s; int ret, batching; uint16_t family, format, outformat; struct mnl_nlmsg_batch *batch; if (argc < 2) { printf("Usage: %s {xml|json} <file>\n", argv[0]); exit(EXIT_FAILURE); } if (strcmp(argv[1], "xml") == 0) { format = NFTNL_PARSE_XML; outformat = NFTNL_OUTPUT_XML; } else if (strcmp(argv[1], "json") == 0) { format = NFTNL_PARSE_JSON; outformat = NFTNL_OUTPUT_JSON; } else { printf("Unknown format: xml, json\n"); exit(EXIT_FAILURE); } s = set_parse_file(argv[2], format); if (s == NULL) exit(EXIT_FAILURE); nftnl_set_fprintf(stdout, s, outformat, 0); fprintf(stdout, "\n"); seq = time(NULL); batching = nftnl_batch_is_supported(); if (batching < 0) { perror("cannot talk to nfnetlink"); exit(EXIT_FAILURE); } batch = mnl_nlmsg_batch_start(buf, sizeof(buf)); if (batching) { nftnl_batch_begin(mnl_nlmsg_batch_current(batch), seq++); mnl_nlmsg_batch_next(batch); } family = nftnl_set_get_u32(s, NFTNL_SET_FAMILY); set_seq = seq; nlh = nftnl_set_nlmsg_build_hdr(mnl_nlmsg_batch_current(batch), NFT_MSG_NEWSET, family, NLM_F_CREATE|NLM_F_ACK, seq++); nftnl_set_nlmsg_build_payload(nlh, s); nftnl_set_free(s); mnl_nlmsg_batch_next(batch); if (batching) { nftnl_batch_end(mnl_nlmsg_batch_current(batch), seq++); mnl_nlmsg_batch_next(batch); } nl = mnl_socket_open(NETLINK_NETFILTER); if (nl == NULL) { perror("mnl_socket_open"); exit(EXIT_FAILURE); } if (mnl_socket_bind(nl, 0, MNL_SOCKET_AUTOPID) < 0) { perror("mnl_socket_bind"); exit(EXIT_FAILURE); } portid = mnl_socket_get_portid(nl); if (mnl_socket_sendto(nl, mnl_nlmsg_batch_head(batch), mnl_nlmsg_batch_size(batch)) < 0) { perror("mnl_socket_send"); exit(EXIT_FAILURE); } mnl_nlmsg_batch_stop(batch); ret = mnl_socket_recvfrom(nl, buf, sizeof(buf)); while (ret > 0) { ret = mnl_cb_run(buf, ret, set_seq, portid, NULL, NULL); if (ret <= 0) break; ret = mnl_socket_recvfrom(nl, buf, sizeof(buf)); } if (ret == -1) { perror("error"); exit(EXIT_FAILURE); } mnl_socket_close(nl); return EXIT_SUCCESS; }
int main(int argc, char *argv[]) { struct mnl_socket *nl; char buf[MNL_SOCKET_BUFFER_SIZE]; struct nlmsghdr *nlh; uint32_t portid, seq, table_seq, family; struct nft_table *t; struct mnl_nlmsg_batch *batch; int ret, batching; if (argc != 3) { fprintf(stderr, "%s <family> <name>\n", argv[0]); exit(EXIT_FAILURE); } t = table_add_parse(argc, argv); if (t == NULL) exit(EXIT_FAILURE); batching = nft_batch_is_supported(); if (batching < 0) { perror("cannot talk to nfnetlink"); exit(EXIT_FAILURE); } seq = time(NULL); batch = mnl_nlmsg_batch_start(buf, sizeof(buf)); if (batching) { nft_batch_begin(mnl_nlmsg_batch_current(batch), seq++); mnl_nlmsg_batch_next(batch); } table_seq = seq; family = nft_table_attr_get_u32(t, NFT_TABLE_ATTR_FAMILY); nlh = nft_table_nlmsg_build_hdr(mnl_nlmsg_batch_current(batch), NFT_MSG_NEWTABLE, family, NLM_F_ACK, seq++); nft_table_nlmsg_build_payload(nlh, t); nft_table_free(t); mnl_nlmsg_batch_next(batch); if (batching) { nft_batch_end(mnl_nlmsg_batch_current(batch), seq++); mnl_nlmsg_batch_next(batch); } nl = mnl_socket_open(NETLINK_NETFILTER); if (nl == NULL) { perror("mnl_socket_open"); exit(EXIT_FAILURE); } if (mnl_socket_bind(nl, 0, MNL_SOCKET_AUTOPID) < 0) { perror("mnl_socket_bind"); exit(EXIT_FAILURE); } portid = mnl_socket_get_portid(nl); if (mnl_socket_sendto(nl, mnl_nlmsg_batch_head(batch), mnl_nlmsg_batch_size(batch)) < 0) { perror("mnl_socket_send"); exit(EXIT_FAILURE); } mnl_nlmsg_batch_stop(batch); ret = mnl_socket_recvfrom(nl, buf, sizeof(buf)); while (ret > 0) { ret = mnl_cb_run(buf, ret, table_seq, portid, NULL, NULL); if (ret <= 0) break; ret = mnl_socket_recvfrom(nl, buf, sizeof(buf)); } if (ret == -1) { perror("error"); exit(EXIT_FAILURE); } mnl_socket_close(nl); return EXIT_SUCCESS; }
int main(void) { struct mnl_socket *nl; struct nlmsghdr *nlh; struct nfgenmsg *nfh; char buf[MNL_SOCKET_BUFFER_SIZE]; unsigned int seq, portid; struct nf_conntrack *ct; int ret; nl = mnl_socket_open(NETLINK_NETFILTER); if (nl == NULL) { perror("mnl_socket_open"); exit(EXIT_FAILURE); } if (mnl_socket_bind(nl, 0, MNL_SOCKET_AUTOPID) < 0) { perror("mnl_socket_bind"); exit(EXIT_FAILURE); } portid = mnl_socket_get_portid(nl); nlh = mnl_nlmsg_put_header(buf); nlh->nlmsg_type = (NFNL_SUBSYS_CTNETLINK << 8) | IPCTNL_MSG_CT_DELETE; nlh->nlmsg_flags = NLM_F_REQUEST|NLM_F_ACK; nlh->nlmsg_seq = seq = time(NULL); nfh = mnl_nlmsg_put_extra_header(nlh, sizeof(struct nfgenmsg)); nfh->nfgen_family = AF_INET; nfh->version = NFNETLINK_V0; nfh->res_id = 0; ct = nfct_new(); if (ct == NULL) { perror("nfct_new"); return 0; } nfct_set_attr_u8(ct, ATTR_L3PROTO, AF_INET); nfct_set_attr_u32(ct, ATTR_IPV4_SRC, inet_addr("1.1.1.1")); nfct_set_attr_u32(ct, ATTR_IPV4_DST, inet_addr("2.2.2.2")); nfct_set_attr_u8(ct, ATTR_L4PROTO, IPPROTO_TCP); nfct_set_attr_u16(ct, ATTR_PORT_SRC, htons(20)); nfct_set_attr_u16(ct, ATTR_PORT_DST, htons(10)); nfct_nlmsg_build(nlh, ct); ret = mnl_socket_sendto(nl, nlh, nlh->nlmsg_len); if (ret == -1) { perror("mnl_socket_recvfrom"); exit(EXIT_FAILURE); } ret = mnl_socket_recvfrom(nl, buf, sizeof(buf)); while (ret > 0) { ret = mnl_cb_run(buf, ret, seq, portid, NULL, NULL); if (ret <= MNL_CB_STOP) break; ret = mnl_socket_recvfrom(nl, buf, sizeof(buf)); } if (ret == -1) { perror("mnl_socket_recvfrom"); exit(EXIT_FAILURE); } mnl_socket_close(nl); return 0; }
struct mnlg_socket *mnlg_socket_open(const char *family_name, uint8_t version) { struct mnlg_socket *nlg; struct nlmsghdr *nlh; int one = 1; int err; nlg = malloc(sizeof(*nlg)); if (!nlg) return NULL; nlg->buf = malloc(MNL_SOCKET_BUFFER_SIZE); if (!nlg->buf) goto err_buf_alloc; nlg->nl = mnl_socket_open(NETLINK_GENERIC); if (!nlg->nl) goto err_mnl_socket_open; err = mnl_socket_setsockopt(nlg->nl, NETLINK_CAP_ACK, &one, sizeof(one)); if (err) goto err_mnl_set_ack; err = mnl_socket_setsockopt(nlg->nl, NETLINK_EXT_ACK, &one, sizeof(one)); if (err) goto err_mnl_set_ext_ack; err = mnl_socket_bind(nlg->nl, 0, MNL_SOCKET_AUTOPID); if (err < 0) goto err_mnl_socket_bind; nlg->portid = mnl_socket_get_portid(nlg->nl); nlh = __mnlg_msg_prepare(nlg, CTRL_CMD_GETFAMILY, NLM_F_REQUEST | NLM_F_ACK, GENL_ID_CTRL, 1); mnl_attr_put_strz(nlh, CTRL_ATTR_FAMILY_NAME, family_name); err = mnlg_socket_send(nlg, nlh); if (err < 0) goto err_mnlg_socket_send; err = mnlg_socket_recv_run(nlg, get_family_id_cb, &nlg->id); if (err < 0) goto err_mnlg_socket_recv_run; nlg->version = version; return nlg; err_mnlg_socket_recv_run: err_mnlg_socket_send: err_mnl_socket_bind: err_mnl_set_ext_ack: err_mnl_set_ack: mnl_socket_close(nlg->nl); err_mnl_socket_open: free(nlg->buf); err_buf_alloc: free(nlg); return NULL; }