libmnl
1.0.3
|
00001 /* This example is placed in the public domain. */ 00002 #include <stdio.h> 00003 #include <stdlib.h> 00004 #include <unistd.h> 00005 #include <time.h> 00006 00007 #include <libmnl/libmnl.h> 00008 #include <linux/if.h> 00009 #include <linux/if_link.h> 00010 #include <linux/rtnetlink.h> 00011 00012 static int data_attr_cb(const struct nlattr *attr, void *data) 00013 { 00014 const struct nlattr **tb = data; 00015 int type = mnl_attr_get_type(attr); 00016 00017 /* skip unsupported attribute in user-space */ 00018 if (mnl_attr_type_valid(attr, IFLA_MAX) < 0) 00019 return MNL_CB_OK; 00020 00021 switch(type) { 00022 case IFLA_MTU: 00023 if (mnl_attr_validate(attr, MNL_TYPE_U32) < 0) { 00024 perror("mnl_attr_validate"); 00025 return MNL_CB_ERROR; 00026 } 00027 break; 00028 case IFLA_IFNAME: 00029 if (mnl_attr_validate(attr, MNL_TYPE_STRING) < 0) { 00030 perror("mnl_attr_validate2"); 00031 return MNL_CB_ERROR; 00032 } 00033 break; 00034 } 00035 tb[type] = attr; 00036 return MNL_CB_OK; 00037 } 00038 00039 static int data_cb(const struct nlmsghdr *nlh, void *data) 00040 { 00041 struct nlattr *tb[IFLA_MAX+1] = {}; 00042 struct ifinfomsg *ifm = mnl_nlmsg_get_payload(nlh); 00043 00044 printf("index=%d type=%d flags=%d family=%d ", 00045 ifm->ifi_index, ifm->ifi_type, 00046 ifm->ifi_flags, ifm->ifi_family); 00047 00048 if (ifm->ifi_flags & IFF_RUNNING) 00049 printf("[RUNNING] "); 00050 else 00051 printf("[NOT RUNNING] "); 00052 00053 mnl_attr_parse(nlh, sizeof(*ifm), data_attr_cb, tb); 00054 if (tb[IFLA_MTU]) { 00055 printf("mtu=%d ", mnl_attr_get_u32(tb[IFLA_MTU])); 00056 } 00057 if (tb[IFLA_IFNAME]) { 00058 printf("name=%s", mnl_attr_get_str(tb[IFLA_IFNAME])); 00059 } 00060 printf("\n"); 00061 return MNL_CB_OK; 00062 } 00063 00064 int main(void) 00065 { 00066 struct mnl_socket *nl; 00067 char buf[MNL_SOCKET_BUFFER_SIZE]; 00068 struct nlmsghdr *nlh; 00069 struct rtgenmsg *rt; 00070 int ret; 00071 unsigned int seq, portid; 00072 00073 nlh = mnl_nlmsg_put_header(buf); 00074 nlh->nlmsg_type = RTM_GETLINK; 00075 nlh->nlmsg_flags = NLM_F_REQUEST | NLM_F_DUMP; 00076 nlh->nlmsg_seq = seq = time(NULL); 00077 rt = mnl_nlmsg_put_extra_header(nlh, sizeof(struct rtgenmsg)); 00078 rt->rtgen_family = AF_PACKET; 00079 00080 nl = mnl_socket_open(NETLINK_ROUTE); 00081 if (nl == NULL) { 00082 perror("mnl_socket_open"); 00083 exit(EXIT_FAILURE); 00084 } 00085 00086 if (mnl_socket_bind(nl, 0, MNL_SOCKET_AUTOPID) < 0) { 00087 perror("mnl_socket_bind"); 00088 exit(EXIT_FAILURE); 00089 } 00090 portid = mnl_socket_get_portid(nl); 00091 00092 if (mnl_socket_sendto(nl, nlh, nlh->nlmsg_len) < 0) { 00093 perror("mnl_socket_send"); 00094 exit(EXIT_FAILURE); 00095 } 00096 00097 ret = mnl_socket_recvfrom(nl, buf, sizeof(buf)); 00098 while (ret > 0) { 00099 ret = mnl_cb_run(buf, ret, seq, portid, data_cb, NULL); 00100 if (ret <= MNL_CB_STOP) 00101 break; 00102 ret = mnl_socket_recvfrom(nl, buf, sizeof(buf)); 00103 } 00104 if (ret == -1) { 00105 perror("error"); 00106 exit(EXIT_FAILURE); 00107 } 00108 00109 mnl_socket_close(nl); 00110 00111 return 0; 00112 }