summaryrefslogtreecommitdiffstats
path: root/examples
diff options
context:
space:
mode:
Diffstat (limited to 'examples')
-rw-r--r--examples/Makefile.am15
-rw-r--r--examples/genl-family-get.c113
-rw-r--r--examples/rtnl-link-dump.c32
-rw-r--r--examples/rtnl-link-dump2.c103
-rw-r--r--examples/rtnl-link-dump3.c101
-rw-r--r--examples/rtnl-link-event.c32
-rw-r--r--examples/rtnl-route-dump.c55
7 files changed, 434 insertions, 17 deletions
diff --git a/examples/Makefile.am b/examples/Makefile.am
index 92c5342..1874971 100644
--- a/examples/Makefile.am
+++ b/examples/Makefile.am
@@ -1,12 +1,23 @@
include $(top_srcdir)/Make_global.am
-check_PROGRAMS = rtnl-link-dump rtnl-link-event rtnl-link-set \
- rtnl-route-dump genl-family-get
+check_PROGRAMS = rtnl-link-dump rtnl-link-dump2 rtnl-link-dump3 \
+ rtnl-link-event \
+ rtnl-link-set \
+ rtnl-route-dump \
+ genl-family-get
rtnl_link_dump_SOURCES = rtnl-link-dump.c
rtnl_link_dump_LDADD = ../src/libmnl.la
rtnl_link_dump_LDFLAGS = -dynamic -ldl
+rtnl_link_dump2_SOURCES = rtnl-link-dump2.c
+rtnl_link_dump2_LDADD = ../src/libmnl.la
+rtnl_link_dump2_LDFLAGS = -dynamic -ldl
+
+rtnl_link_dump3_SOURCES = rtnl-link-dump3.c
+rtnl_link_dump3_LDADD = ../src/libmnl.la
+rtnl_link_dump3_LDFLAGS = -dynamic -ldl
+
rtnl_link_event_SOURCES = rtnl-link-event.c
rtnl_link_event_LDADD = ../src/libmnl.la
rtnl_link_event_LDFLAGS = -dynamic -ldl
diff --git a/examples/genl-family-get.c b/examples/genl-family-get.c
index 3e741cb..00f601c 100644
--- a/examples/genl-family-get.c
+++ b/examples/genl-family-get.c
@@ -5,15 +5,43 @@
#include <libmnl/libmnl.h>
#include <linux/genetlink.h>
+static int parse_mc_grps_cb(const struct nlattr *attr, void *data)
+{
+ const struct nlattr **tb = (const struct nlattr **)data;
+ int type = mnl_attr_get_type(attr);
+
+ if (mnl_attr_type_invalid(attr, CTRL_ATTR_MCAST_GRP_MAX) < 0) {
+ perror("mnl_attr_type_invalid");
+ return MNL_CB_ERROR;
+ }
+
+ switch(type) {
+ case CTRL_ATTR_MCAST_GRP_ID:
+ if (mnl_attr_validate(attr, MNL_TYPE_U32) < 0) {
+ perror("mnl_attr_validate");
+ return MNL_CB_ERROR;
+ }
+ break;
+ case CTRL_ATTR_MCAST_GRP_NAME:
+ if (mnl_attr_validate(attr, MNL_TYPE_STRING) < 0) {
+ perror("mnl_attr_validate");
+ return MNL_CB_ERROR;
+ }
+ break;
+ }
+ tb[type] = attr;
+ return MNL_CB_OK;
+}
+
static void parse_genl_mc_grps(struct nlattr *nested)
{
struct nlattr *pos;
int len;
- mnl_attr_for_each_nested(pos, nested, len) {
- struct nlattr *tb[CTRL_ATTR_MCAST_GRP_MAX+1];
+ mnl_attr_for_each_nested(pos, nested) {
+ struct nlattr *tb[CTRL_ATTR_MCAST_GRP_MAX+1] = {};
- mnl_attr_parse_nested(pos, tb, CTRL_ATTR_MCAST_GRP_MAX);
+ mnl_attr_parse_nested(pos, parse_mc_grps_cb, tb);
if (tb[CTRL_ATTR_MCAST_GRP_ID]) {
printf("id-0x%x ",
mnl_attr_get_u32(tb[CTRL_ATTR_MCAST_GRP_ID]));
@@ -26,15 +54,41 @@ static void parse_genl_mc_grps(struct nlattr *nested)
}
}
+static int parse_family_ops_cb(const struct nlattr *attr, void *data)
+{
+ const struct nlattr **tb = (const struct nlattr **)data;
+ int type = mnl_attr_get_type(attr);
+
+ if (mnl_attr_type_invalid(attr, CTRL_ATTR_OP_MAX) < 0) {
+ perror("mnl_attr_type_invalid");
+ return MNL_CB_ERROR;
+ }
+
+ switch(type) {
+ case CTRL_ATTR_OP_ID:
+ if (mnl_attr_validate(attr, MNL_TYPE_U32) < 0) {
+ perror("mnl_attr_validate");
+ return MNL_CB_ERROR;
+ }
+ break;
+ case CTRL_ATTR_OP_MAX:
+ break;
+ default:
+ return MNL_CB_OK;
+ }
+ tb[type] = attr;
+ return MNL_CB_OK;
+}
+
static void parse_genl_family_ops(struct nlattr *nested)
{
struct nlattr *pos;
int len;
- mnl_attr_for_each_nested(pos, nested, len) {
- struct nlattr *tb[CTRL_ATTR_OP_MAX+1];
+ mnl_attr_for_each_nested(pos, nested) {
+ struct nlattr *tb[CTRL_ATTR_OP_MAX+1] = {};
- mnl_attr_parse_nested(pos, tb, CTRL_ATTR_OP_MAX);
+ mnl_attr_parse_nested(pos, parse_family_ops_cb, tb);
if (tb[CTRL_ATTR_OP_ID]) {
printf("id-0x%x ",
mnl_attr_get_u32(tb[CTRL_ATTR_OP_ID]));
@@ -46,12 +100,55 @@ static void parse_genl_family_ops(struct nlattr *nested)
}
}
+static int data_attr_cb(const struct nlattr *attr, void *data)
+{
+ const struct nlattr **tb = (const struct nlattr **)data;
+ int type = mnl_attr_get_type(attr);
+
+ if (mnl_attr_type_invalid(attr, CTRL_ATTR_MAX) < 0) {
+ perror("mnl_attr_type_invalid");
+ return MNL_CB_ERROR;
+ }
+
+ switch(type) {
+ case CTRL_ATTR_FAMILY_NAME:
+ if (mnl_attr_validate(attr, MNL_TYPE_STRING) < 0) {
+ perror("mnl_attr_validate");
+ return MNL_CB_ERROR;
+ }
+ break;
+ case CTRL_ATTR_FAMILY_ID:
+ if (mnl_attr_validate(attr, MNL_TYPE_U16) < 0) {
+ perror("mnl_attr_validate");
+ return MNL_CB_ERROR;
+ }
+ break;
+ case CTRL_ATTR_VERSION:
+ case CTRL_ATTR_HDRSIZE:
+ case CTRL_ATTR_MAXATTR:
+ if (mnl_attr_validate(attr, MNL_TYPE_U32) < 0) {
+ perror("mnl_attr_validate");
+ return MNL_CB_ERROR;
+ }
+ break;
+ case CTRL_ATTR_OPS:
+ case CTRL_ATTR_MCAST_GROUPS:
+ if (mnl_attr_validate(attr, MNL_TYPE_NESTED) < 0) {
+ perror("mnl_attr_validate");
+ return MNL_CB_ERROR;
+ }
+ break;
+ }
+ tb[type] = attr;
+ return MNL_CB_OK;
+}
+
static int data_cb(const struct nlmsghdr *nlh, void *data)
{
- struct nlattr *tb[CTRL_ATTR_MAX+1];
+ struct nlattr *tb[CTRL_ATTR_MAX+1] = {};
struct genlmsghdr *genl = mnl_nlmsg_get_data(nlh);
- mnl_attr_parse_at_offset(nlh, sizeof(*genl), tb, CTRL_ATTR_MAX);
+ mnl_attr_parse(nlh, sizeof(*genl), data_attr_cb, tb);
if (tb[CTRL_ATTR_FAMILY_NAME]) {
printf("name=%s\t",
mnl_attr_get_str(tb[CTRL_ATTR_FAMILY_NAME]));
diff --git a/examples/rtnl-link-dump.c b/examples/rtnl-link-dump.c
index 7cf061d..9e3f114 100644
--- a/examples/rtnl-link-dump.c
+++ b/examples/rtnl-link-dump.c
@@ -7,9 +7,37 @@
#include <linux/if_link.h>
#include <linux/rtnetlink.h>
+static int data_attr_cb(const struct nlattr *attr, void *data)
+{
+ const struct nlattr **tb = (const struct nlattr **)data;
+ int type = mnl_attr_get_type(attr);
+
+ if (mnl_attr_type_invalid(attr, IFLA_MAX) < 0) {
+ perror("mnl_attr_type_invalid");
+ return MNL_CB_ERROR;
+ }
+
+ switch(type) {
+ case IFLA_MTU:
+ if (mnl_attr_validate(attr, MNL_TYPE_U32) < 0) {
+ perror("mnl_attr_validate");
+ return MNL_CB_ERROR;
+ }
+ break;
+ case IFLA_IFNAME:
+ if (mnl_attr_validate(attr, MNL_TYPE_STRING) < 0) {
+ perror("mnl_attr_validate2");
+ return MNL_CB_ERROR;
+ }
+ break;
+ }
+ tb[type] = attr;
+ return MNL_CB_OK;
+}
+
static int data_cb(const struct nlmsghdr *nlh, void *data)
{
- struct nlattr *tb[IFLA_MAX+1];
+ struct nlattr *tb[IFLA_MAX+1] = {};
struct ifinfomsg *ifm = mnl_nlmsg_get_data(nlh);
int len = mnl_nlmsg_get_len(nlh);
struct nlattr *attr;
@@ -23,7 +51,7 @@ static int data_cb(const struct nlmsghdr *nlh, void *data)
else
printf("[NOT RUNNING] ");
- mnl_attr_parse_at_offset(nlh, sizeof(*ifm), tb, IFLA_MAX);
+ mnl_attr_parse(nlh, sizeof(*ifm), data_attr_cb, tb);
if (tb[IFLA_MTU]) {
printf("mtu=%d ", mnl_attr_get_u32(tb[IFLA_MTU]));
}
diff --git a/examples/rtnl-link-dump2.c b/examples/rtnl-link-dump2.c
new file mode 100644
index 0000000..dc44c54
--- /dev/null
+++ b/examples/rtnl-link-dump2.c
@@ -0,0 +1,103 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include <libmnl/libmnl.h>
+#include <linux/if.h>
+#include <linux/if_link.h>
+#include <linux/rtnetlink.h>
+
+static int data_attr_cb(const struct nlattr *attr, void *data)
+{
+ if (mnl_attr_type_invalid(attr, IFLA_MAX) < 0) {
+ perror("mnl_attr_type_invalid");
+ return MNL_CB_ERROR;
+ }
+
+ switch(mnl_attr_get_type(attr)) {
+ case IFLA_MTU:
+ if (mnl_attr_validate(attr, MNL_TYPE_U32) < 0) {
+ perror("mnl_attr_validate");
+ return MNL_CB_ERROR;
+ }
+ printf("mtu=%d ", mnl_attr_get_u32(attr));
+ break;
+ case IFLA_IFNAME:
+ if (mnl_attr_validate(attr, MNL_TYPE_STRING) < 0) {
+ perror("mnl_attr_validate2");
+ return MNL_CB_ERROR;
+ }
+ printf("name=%s ", mnl_attr_get_str(attr));
+ break;
+ }
+ return MNL_CB_OK;
+}
+
+static int data_cb(const struct nlmsghdr *nlh, void *data)
+{
+ struct ifinfomsg *ifm = mnl_nlmsg_get_data(nlh);
+ int len = mnl_nlmsg_get_len(nlh);
+ struct nlattr *attr;
+
+ printf("index=%d type=%d flags=%d family=%d ",
+ ifm->ifi_index, ifm->ifi_type,
+ ifm->ifi_flags, ifm->ifi_family);
+
+ if (ifm->ifi_flags & IFF_RUNNING)
+ printf("[RUNNING] ");
+ else
+ printf("[NOT RUNNING] ");
+
+ mnl_attr_parse(nlh, sizeof(*ifm), data_attr_cb, NULL);
+ printf("\n");
+ return MNL_CB_OK;
+}
+
+int main()
+{
+ struct mnl_socket *nl;
+ char buf[getpagesize()];
+ struct nlmsghdr *nlh;
+ struct rtgenmsg *rt;
+ int ret;
+ unsigned int seq;
+
+ 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);
+ }
+
+ if (mnl_socket_sendto(nl, nlh, mnl_nlmsg_get_len(nlh)) < 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, 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;
+}
diff --git a/examples/rtnl-link-dump3.c b/examples/rtnl-link-dump3.c
new file mode 100644
index 0000000..d5e4458
--- /dev/null
+++ b/examples/rtnl-link-dump3.c
@@ -0,0 +1,101 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include <libmnl/libmnl.h>
+#include <linux/if.h>
+#include <linux/if_link.h>
+#include <linux/rtnetlink.h>
+
+static int data_cb(const struct nlmsghdr *nlh, void *data)
+{
+ struct ifinfomsg *ifm = mnl_nlmsg_get_data(nlh);
+ int len = mnl_nlmsg_get_len(nlh);
+ struct nlattr *attr;
+
+ printf("index=%d type=%d flags=%d family=%d ",
+ ifm->ifi_index, ifm->ifi_type,
+ ifm->ifi_flags, ifm->ifi_family);
+
+ if (ifm->ifi_flags & IFF_RUNNING)
+ printf("[RUNNING] ");
+ else
+ printf("[NOT RUNNING] ");
+
+ mnl_attr_for_each(attr, nlh, sizeof(*ifm)) {
+ int type = mnl_attr_get_type(attr);
+
+ if (mnl_attr_type_invalid(attr, IFLA_MAX) < 0) {
+ perror("mnl_attr_type_invalid");
+ return MNL_CB_ERROR;
+ }
+ switch(type) {
+ case IFLA_MTU:
+ if (mnl_attr_validate(attr, MNL_TYPE_U32) < 0) {
+ perror("mnl_attr_validate");
+ return MNL_CB_ERROR;
+ }
+ printf("mtu=%d ", mnl_attr_get_u32(attr));
+ break;
+ case IFLA_IFNAME:
+ if (mnl_attr_validate(attr, MNL_TYPE_STRING) < 0) {
+ perror("mnl_attr_validate");
+ return MNL_CB_ERROR;
+ }
+ printf("name=%s ", mnl_attr_get_str(attr));
+ break;
+ }
+ }
+ printf("\n");
+
+ return MNL_CB_OK;
+}
+
+int main()
+{
+ struct mnl_socket *nl;
+ char buf[getpagesize()];
+ struct nlmsghdr *nlh;
+ struct rtgenmsg *rt;
+ int ret;
+ unsigned int seq;
+
+ 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);
+ }
+
+ if (mnl_socket_sendto(nl, nlh, mnl_nlmsg_get_len(nlh)) < 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, 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;
+}
diff --git a/examples/rtnl-link-event.c b/examples/rtnl-link-event.c
index ed5a577..3e25b6f 100644
--- a/examples/rtnl-link-event.c
+++ b/examples/rtnl-link-event.c
@@ -7,9 +7,37 @@
#include <linux/if_link.h>
#include <linux/rtnetlink.h>
+static int data_attr_cb(const struct nlattr *attr, void *data)
+{
+ const struct nlattr **tb = (const struct nlattr **)data;
+ int type = mnl_attr_get_type(attr);
+
+ if (mnl_attr_type_invalid(attr, IFLA_MAX) < 0) {
+ perror("mnl_attr_type_invalid");
+ return MNL_CB_ERROR;
+ }
+
+ switch(type) {
+ case IFLA_MTU:
+ if (mnl_attr_validate(attr, MNL_TYPE_U32) < 0) {
+ perror("mnl_attr_validate");
+ return MNL_CB_ERROR;
+ }
+ break;
+ case IFLA_IFNAME:
+ if (mnl_attr_validate(attr, MNL_TYPE_STRING) < 0) {
+ perror("mnl_attr_validate2");
+ return MNL_CB_ERROR;
+ }
+ break;
+ }
+ tb[type] = attr;
+ return MNL_CB_OK;
+}
+
static int data_cb(const struct nlmsghdr *nlh, void *data)
{
- struct nlattr *tb[IFLA_MAX+1];
+ struct nlattr *tb[IFLA_MAX+1] = {};
struct ifinfomsg *ifm = mnl_nlmsg_get_data(nlh);
int len = mnl_nlmsg_get_len(nlh);
struct nlattr *attr;
@@ -23,7 +51,7 @@ static int data_cb(const struct nlmsghdr *nlh, void *data)
else
printf("[NOT RUNNING] ");
- mnl_attr_parse_at_offset(nlh, sizeof(*ifm), tb, IFLA_MAX);
+ mnl_attr_parse(nlh, sizeof(*ifm), data_attr_cb, tb);
if (tb[IFLA_MTU]) {
printf("mtu=%d ", mnl_attr_get_u32(tb[IFLA_MTU]));
}
diff --git a/examples/rtnl-route-dump.c b/examples/rtnl-route-dump.c
index e8f3a0c..eb36bbc 100644
--- a/examples/rtnl-route-dump.c
+++ b/examples/rtnl-route-dump.c
@@ -7,6 +7,22 @@
#include <linux/if_link.h>
#include <linux/rtnetlink.h>
+static int data_attr_cb2(const struct nlattr *attr, void *data)
+{
+ const struct nlattr **tb = (const struct nlattr **)data;
+ int type = mnl_attr_get_type(attr);
+
+ if (mnl_attr_type_invalid(attr, RTAX_MAX) < 0) {
+ perror("mnl_attr_type_invalid");
+ return MNL_CB_ERROR;
+ }
+ if (mnl_attr_validate(attr, MNL_TYPE_U32) < 0) {
+ perror("mnl_attr_validate");
+ return MNL_CB_ERROR;
+ }
+ return MNL_CB_OK;
+}
+
static void attributes_show_ipv4(struct nlattr *tb[])
{
if (tb[RTA_TABLE]) {
@@ -35,7 +51,7 @@ static void attributes_show_ipv4(struct nlattr *tb[])
int i;
struct nlattr *tbx[RTAX_MAX+1] = {};
- mnl_attr_parse_nested(tb[RTA_METRICS], tbx, RTAX_MAX);
+ mnl_attr_parse_nested(tb[RTA_METRICS], data_attr_cb2, tbx);
for (i=0; i<RTAX_MAX; i++) {
if (tbx[i]) {
@@ -47,9 +63,42 @@ static void attributes_show_ipv4(struct nlattr *tb[])
printf("\n");
}
+static int data_attr_cb(const struct nlattr *attr, void *data)
+{
+ const struct nlattr **tb = (const struct nlattr **)data;
+ int type = mnl_attr_get_type(attr);
+
+ if (mnl_attr_type_invalid(attr, RTA_MAX) < 0) {
+ perror("mnl_attr_type_invalid");
+ return MNL_CB_ERROR;
+ }
+
+ switch(type) {
+ case RTA_TABLE:
+ case RTA_DST:
+ case RTA_SRC:
+ case RTA_OIF:
+ case RTA_FLOW:
+ case RTA_PREFSRC:
+ case RTA_GATEWAY:
+ if (mnl_attr_validate(attr, MNL_TYPE_U32) < 0) {
+ perror("mnl_attr_validate");
+ return MNL_CB_ERROR;
+ }
+ break;
+ case RTA_METRICS:
+ if (mnl_attr_validate(attr, MNL_TYPE_NESTED) < 0) {
+ perror("mnl_attr_validate");
+ return MNL_CB_ERROR;
+ }
+ break;
+ }
+ tb[type] = attr;
+ return MNL_CB_OK;
+}
+
static int data_cb(const struct nlmsghdr *nlh, void *data)
{
- /* parse() ya está inicializando este array, qué hacer ? */
struct nlattr *tb[RTA_MAX+1] = {};
struct rtmsg *rm = mnl_nlmsg_get_data(nlh);
int len = mnl_nlmsg_get_len(nlh);
@@ -131,7 +180,7 @@ static int data_cb(const struct nlmsghdr *nlh, void *data)
*/
printf("flags=%x\n", rm->rtm_flags);
- mnl_attr_parse_at_offset(nlh, sizeof(*rm), tb, RTA_MAX);
+ mnl_attr_parse(nlh, sizeof(*rm), data_attr_cb, tb);
switch(rm->rtm_family) {
case AF_INET: