diff options
Diffstat (limited to 'examples')
-rw-r--r-- | examples/Makefile.am | 15 | ||||
-rw-r--r-- | examples/genl-family-get.c | 113 | ||||
-rw-r--r-- | examples/rtnl-link-dump.c | 32 | ||||
-rw-r--r-- | examples/rtnl-link-dump2.c | 103 | ||||
-rw-r--r-- | examples/rtnl-link-dump3.c | 101 | ||||
-rw-r--r-- | examples/rtnl-link-event.c | 32 | ||||
-rw-r--r-- | examples/rtnl-route-dump.c | 55 |
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: |