summaryrefslogtreecommitdiffstats
path: root/examples
diff options
context:
space:
mode:
Diffstat (limited to 'examples')
-rw-r--r--examples/Makefile.am10
-rw-r--r--examples/nfct-mnl-dump-labels.c103
-rw-r--r--examples/nfct-mnl-set-label.c182
3 files changed, 295 insertions, 0 deletions
diff --git a/examples/Makefile.am b/examples/Makefile.am
index 55bd750..a366390 100644
--- a/examples/Makefile.am
+++ b/examples/Makefile.am
@@ -3,6 +3,8 @@ include $(top_srcdir)/Make_global.am
check_PROGRAMS = nfct-mnl-create \
nfct-mnl-del \
nfct-mnl-dump \
+ nfct-mnl-dump-labels \
+ nfct-mnl-set-label \
nfct-mnl-event \
nfct-mnl-flush \
nfct-mnl-get \
@@ -21,6 +23,14 @@ nfct_mnl_dump_SOURCES = nfct-mnl-dump.c
nfct_mnl_dump_LDADD = ../src/libnetfilter_conntrack.la
nfct_mnl_dump_LDFLAGS = -dynamic -ldl -lmnl
+nfct_mnl_dump_labels_SOURCES = nfct-mnl-dump-labels.c
+nfct_mnl_dump_labels_LDADD = ../src/libnetfilter_conntrack.la
+nfct_mnl_dump_labels_LDFLAGS = -dynamic -ldl -lmnl
+
+nfct_mnl_set_label_SOURCES = nfct-mnl-set-label.c
+nfct_mnl_set_label_LDADD = ../src/libnetfilter_conntrack.la
+nfct_mnl_set_label_LDFLAGS = -dynamic -ldl -lmnl
+
nfct_mnl_event_SOURCES = nfct-mnl-event.c
nfct_mnl_event_LDADD = ../src/libnetfilter_conntrack.la
nfct_mnl_event_LDFLAGS = -dynamic -ldl -lmnl
diff --git a/examples/nfct-mnl-dump-labels.c b/examples/nfct-mnl-dump-labels.c
new file mode 100644
index 0000000..98df430
--- /dev/null
+++ b/examples/nfct-mnl-dump-labels.c
@@ -0,0 +1,103 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <time.h>
+
+#include <libmnl/libmnl.h>
+#include <libnetfilter_conntrack/libnetfilter_conntrack.h>
+
+static void print_label(struct nf_conntrack *ct, struct nfct_labelmap *map)
+{
+ unsigned int i, max;
+ const struct nfct_bitmask *b = nfct_get_attr(ct, ATTR_CONNLABELS);
+ if (!b)
+ return;
+
+ puts("labels:");
+ max = nfct_bitmask_maxbit(b);
+ for (i = 0; i <= max; i++) {
+ if (nfct_bitmask_test_bit(b, i))
+ printf("\t'%s' (%d)\n", map ? nfct_labelmap_get_name(map, i) : "", i);
+ }
+}
+
+static int data_cb(const struct nlmsghdr *nlh, void *data)
+{
+ struct nf_conntrack *ct;
+ char buf[4096];
+
+ ct = nfct_new();
+ if (ct == NULL)
+ return MNL_CB_OK;
+
+ nfct_nlmsg_parse(nlh, ct);
+
+ nfct_snprintf(buf, sizeof(buf), ct, NFCT_T_UNKNOWN, NFCT_O_DEFAULT, 0);
+ printf("%s\n", buf);
+
+ print_label(ct, data);
+
+ nfct_destroy(ct);
+
+ return MNL_CB_OK;
+}
+
+int main(void)
+{
+ struct mnl_socket *nl;
+ struct nlmsghdr *nlh;
+ struct nfgenmsg *nfh;
+ char buf[MNL_SOCKET_BUFFER_SIZE];
+ unsigned int seq, portid;
+ int ret;
+ struct nfct_labelmap *l = nfct_labelmap_new(NULL);
+
+ 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_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_UNSPEC;
+ 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);
+ }
+
+ ret = mnl_socket_recvfrom(nl, buf, sizeof(buf));
+
+
+ while (ret > 0) {
+ ret = mnl_cb_run(buf, ret, seq, portid, data_cb, l);
+ if (ret <= MNL_CB_STOP)
+ break;
+ ret = mnl_socket_recvfrom(nl, buf, sizeof(buf));
+ }
+ if (ret == -1) {
+ perror("mnl_socket_recvfrom");
+ exit(EXIT_FAILURE);
+ }
+
+ if (l)
+ nfct_labelmap_destroy(l);
+
+ mnl_socket_close(nl);
+
+ return 0;
+}
diff --git a/examples/nfct-mnl-set-label.c b/examples/nfct-mnl-set-label.c
new file mode 100644
index 0000000..9e7fbf6
--- /dev/null
+++ b/examples/nfct-mnl-set-label.c
@@ -0,0 +1,182 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+
+#include <libmnl/libmnl.h>
+#include <libnetfilter_conntrack/libnetfilter_conntrack.h>
+
+struct callback_args {
+ struct mnl_socket *nl;
+ unsigned int seq;
+ int bit;
+};
+
+static void set_label(struct nf_conntrack *ct, struct callback_args *cbargs)
+{
+ struct nfct_bitmask *b = (void *) nfct_get_attr(ct, ATTR_CONNLABELS);
+ int bit = cbargs->bit;
+ char buf[MNL_SOCKET_BUFFER_SIZE];
+ struct nlmsghdr *nlh;
+ struct nfgenmsg *nfh;
+
+ if (b) {
+ if (bit < 0)
+ b = nfct_bitmask_new(0);
+ else if (nfct_bitmask_test_bit(b, bit))
+ return;
+ } else {
+ b = nfct_bitmask_new(0);
+ }
+
+ if (!b)
+ return;
+ if (bit >= 0)
+ nfct_bitmask_set_bit(b, bit);
+ nfct_set_attr(ct, ATTR_CONNLABELS, b);
+
+ cbargs->seq++;
+
+ nlh = mnl_nlmsg_put_header(buf);
+ nlh->nlmsg_type = (NFNL_SUBSYS_CTNETLINK << 8) | IPCTNL_MSG_CT_NEW;
+ nlh->nlmsg_flags = NLM_F_REQUEST|NLM_F_CREATE;
+ nlh->nlmsg_seq = cbargs->seq;
+
+ nfh = mnl_nlmsg_put_extra_header(nlh, sizeof(struct nfgenmsg));
+ nfh->nfgen_family = nfct_get_attr_u8(ct, ATTR_L3PROTO);
+ nfh->version = NFNETLINK_V0;
+ nfh->res_id = 0;
+
+ nfct_nlmsg_build(nlh, ct);
+
+ if (mnl_socket_sendto(cbargs->nl, nlh, nlh->nlmsg_len) < 0)
+ perror("mnl_socket_sendto");
+}
+
+static int data_cb(const struct nlmsghdr *nlh, void *data)
+{
+ struct nf_conntrack *ct;
+ char buf[4096];
+
+ ct = nfct_new();
+ if (ct == NULL)
+ return MNL_CB_OK;
+
+ nfct_nlmsg_parse(nlh, ct);
+
+ nfct_snprintf(buf, sizeof(buf), ct, NFCT_T_UNKNOWN, NFCT_O_DEFAULT, 0);
+ printf("%s\n", buf);
+
+ set_label(ct, data);
+
+ nfct_destroy(ct);
+
+ return MNL_CB_OK;
+}
+
+static void show_labels(struct nfct_labelmap *l)
+{
+ unsigned int i = 0;
+ const char *name;
+
+ if (l) {
+ fputs("usage: program label, configured labels are:\n", stderr);
+ while ((name = nfct_labelmap_get_name(l, i))) {
+ if (*name)
+ fprintf(stderr, "%s -> bit %d\n", name, i);
+ i++;
+ }
+ } else {
+ fputs("no labels configured, usage: program bit\n", stderr);
+ }
+ exit(1);
+}
+
+static struct mnl_socket *sock_nl_create(void)
+{
+ struct mnl_socket *nl;
+
+ 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);
+ }
+
+ return nl;
+}
+
+int main(int argc, char *argv[])
+{
+ struct mnl_socket *nl;
+ struct nlmsghdr *nlh;
+ struct nfgenmsg *nfh;
+ char buf[MNL_SOCKET_BUFFER_SIZE];
+ unsigned int seq, portid;
+ struct callback_args cbargs;
+ int ret;
+ struct nfct_labelmap *l = nfct_labelmap_new(NULL);
+
+ if (argc < 2)
+ show_labels(l);
+
+ cbargs.bit = l ? nfct_labelmap_get_bit(l, argv[1]) : -1;
+
+ if (cbargs.bit < 0) {
+ cbargs.bit = atoi(argv[1]);
+ if (cbargs.bit == 0 && argv[1][0] != '0')
+ show_labels(l);
+ }
+
+ if (cbargs.bit < 0)
+ puts("will clear all labels");
+ else
+ printf("will set label bit %d\n", cbargs.bit);
+
+ nl = sock_nl_create();
+ portid = mnl_socket_get_portid(nl);
+
+ 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_UNSPEC;
+ 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);
+ }
+
+ ret = mnl_socket_recvfrom(nl, buf, sizeof(buf));
+
+
+ cbargs.nl = sock_nl_create();
+ cbargs.seq = seq;
+
+ while (ret > 0) {
+ ret = mnl_cb_run(buf, ret, seq, portid, data_cb, &cbargs);
+ if (ret <= MNL_CB_STOP)
+ break;
+ ret = mnl_socket_recvfrom(nl, buf, sizeof(buf));
+ }
+ if (ret == -1) {
+ perror("mnl_socket_recvfrom");
+ exit(EXIT_FAILURE);
+ }
+
+ if (l)
+ nfct_labelmap_destroy(l);
+ mnl_socket_close(nl);
+
+ return 0;
+}