• Main Page
  • Modules
  • Data Structures
  • Files
  • File List

genl-family-get.c

00001 /*
00002  * (C) 2009-2010 by Pablo Neira Ayuso <pablo@netfilter.org>
00003  *
00004  * This software may be used and distributed according to the terms
00005  * of the GNU General Public License, incorporated herein by reference.
00006  */
00007 #include <stdio.h>
00008 #include <stdlib.h>
00009 #include <unistd.h>
00010 #include <time.h>
00011 
00012 #include <libmnl/libmnl.h>
00013 #include <linux/genetlink.h>
00014 
00015 static int parse_mc_grps_cb(const struct nlattr *attr, void *data)
00016 {
00017         const struct nlattr **tb = data;
00018         int type = mnl_attr_get_type(attr);
00019 
00020         /* skip unsupported attribute in user-space */
00021         if (mnl_attr_type_valid(attr, CTRL_ATTR_MCAST_GRP_MAX) < 0)
00022                 return MNL_CB_OK;
00023 
00024         switch(type) {
00025         case CTRL_ATTR_MCAST_GRP_ID:
00026                 if (mnl_attr_validate(attr, MNL_TYPE_U32) < 0) {
00027                         perror("mnl_attr_validate");
00028                         return MNL_CB_ERROR;
00029                 }
00030                 break;
00031         case CTRL_ATTR_MCAST_GRP_NAME:
00032                 if (mnl_attr_validate(attr, MNL_TYPE_STRING) < 0) {
00033                         perror("mnl_attr_validate");
00034                         return MNL_CB_ERROR;
00035                 }
00036                 break;
00037         }
00038         tb[type] = attr;
00039         return MNL_CB_OK;
00040 }
00041 
00042 static void parse_genl_mc_grps(struct nlattr *nested)
00043 {
00044         struct nlattr *pos;
00045 
00046         mnl_attr_for_each_nested(pos, nested) {
00047                 struct nlattr *tb[CTRL_ATTR_MCAST_GRP_MAX+1] = {};
00048 
00049                 mnl_attr_parse_nested(pos, parse_mc_grps_cb, tb);
00050                 if (tb[CTRL_ATTR_MCAST_GRP_ID]) {
00051                         printf("id-0x%x ",
00052                                 mnl_attr_get_u32(tb[CTRL_ATTR_MCAST_GRP_ID]));
00053                 }
00054                 if (tb[CTRL_ATTR_MCAST_GRP_NAME]) {
00055                         printf("name: %s ",
00056                                 mnl_attr_get_str(tb[CTRL_ATTR_MCAST_GRP_NAME]));
00057                 }
00058                 printf("\n");
00059         }
00060 }
00061 
00062 static int parse_family_ops_cb(const struct nlattr *attr, void *data)
00063 {
00064         const struct nlattr **tb = data;
00065         int type = mnl_attr_get_type(attr);
00066 
00067         if (mnl_attr_type_valid(attr, CTRL_ATTR_OP_MAX) < 0)
00068                 return MNL_CB_OK;
00069 
00070         switch(type) {
00071         case CTRL_ATTR_OP_ID:
00072                 if (mnl_attr_validate(attr, MNL_TYPE_U32) < 0) {
00073                         perror("mnl_attr_validate");
00074                         return MNL_CB_ERROR;
00075                 }
00076                 break;
00077         case CTRL_ATTR_OP_MAX:
00078                 break;
00079         default:
00080                 return MNL_CB_OK;
00081         }
00082         tb[type] = attr;
00083         return MNL_CB_OK;
00084 }
00085 
00086 static void parse_genl_family_ops(struct nlattr *nested)
00087 {
00088         struct nlattr *pos;
00089 
00090         mnl_attr_for_each_nested(pos, nested) {
00091                 struct nlattr *tb[CTRL_ATTR_OP_MAX+1] = {};
00092 
00093                 mnl_attr_parse_nested(pos, parse_family_ops_cb, tb);
00094                 if (tb[CTRL_ATTR_OP_ID]) {
00095                         printf("id-0x%x ",
00096                                 mnl_attr_get_u32(tb[CTRL_ATTR_OP_ID]));
00097                 }
00098                 if (tb[CTRL_ATTR_OP_MAX]) {
00099                         printf("flags ");
00100                 }
00101                 printf("\n");
00102         }
00103 }
00104 
00105 static int data_attr_cb(const struct nlattr *attr, void *data)
00106 {
00107         const struct nlattr **tb = data;
00108         int type = mnl_attr_get_type(attr);
00109 
00110         if (mnl_attr_type_valid(attr, CTRL_ATTR_MAX) < 0)
00111                 return MNL_CB_OK;
00112 
00113         switch(type) {
00114         case CTRL_ATTR_FAMILY_NAME:
00115                 if (mnl_attr_validate(attr, MNL_TYPE_STRING) < 0) {
00116                         perror("mnl_attr_validate");
00117                         return MNL_CB_ERROR;
00118                 }
00119                 break;
00120         case CTRL_ATTR_FAMILY_ID:
00121                 if (mnl_attr_validate(attr, MNL_TYPE_U16) < 0) {
00122                         perror("mnl_attr_validate");
00123                         return MNL_CB_ERROR;
00124                 }
00125                 break;
00126         case CTRL_ATTR_VERSION:
00127         case CTRL_ATTR_HDRSIZE:
00128         case CTRL_ATTR_MAXATTR:
00129                 if (mnl_attr_validate(attr, MNL_TYPE_U32) < 0) {
00130                         perror("mnl_attr_validate");
00131                         return MNL_CB_ERROR;
00132                 }
00133                 break;
00134         case CTRL_ATTR_OPS:
00135         case CTRL_ATTR_MCAST_GROUPS:
00136                 if (mnl_attr_validate(attr, MNL_TYPE_NESTED) < 0) {
00137                         perror("mnl_attr_validate");
00138                         return MNL_CB_ERROR;
00139                 }
00140                 break;
00141         }
00142         tb[type] = attr;
00143         return MNL_CB_OK;
00144 }
00145 
00146 static int data_cb(const struct nlmsghdr *nlh, void *data)
00147 {
00148         struct nlattr *tb[CTRL_ATTR_MAX+1] = {};
00149         struct genlmsghdr *genl = mnl_nlmsg_get_payload(nlh);
00150 
00151         mnl_attr_parse(nlh, sizeof(*genl), data_attr_cb, tb);
00152         if (tb[CTRL_ATTR_FAMILY_NAME]) {
00153                 printf("name=%s\t",
00154                         mnl_attr_get_str(tb[CTRL_ATTR_FAMILY_NAME]));
00155         }
00156         if (tb[CTRL_ATTR_FAMILY_ID]) {
00157                 printf("id=%u\t",
00158                         mnl_attr_get_u16(tb[CTRL_ATTR_FAMILY_ID]));
00159         }
00160         if (tb[CTRL_ATTR_VERSION]) {
00161                 printf("version=%u\t",
00162                         mnl_attr_get_u32(tb[CTRL_ATTR_VERSION]));
00163         }
00164         if (tb[CTRL_ATTR_HDRSIZE]) {
00165                 printf("hdrsize=%u\t",
00166                         mnl_attr_get_u32(tb[CTRL_ATTR_HDRSIZE]));
00167         }
00168         if (tb[CTRL_ATTR_MAXATTR]) {
00169                 printf("maxattr=%u\t",
00170                         mnl_attr_get_u32(tb[CTRL_ATTR_MAXATTR]));
00171         }
00172         if (tb[CTRL_ATTR_OPS]) {
00173                 printf("\nops:\n");
00174                 parse_genl_family_ops(tb[CTRL_ATTR_OPS]);
00175         }
00176         if (tb[CTRL_ATTR_MCAST_GROUPS]) {
00177                 printf("\ngrps:\n");
00178                 parse_genl_mc_grps(tb[CTRL_ATTR_MCAST_GROUPS]);
00179         }
00180         return MNL_CB_OK;
00181 }
00182 
00183 int main(int argc, char *argv[])
00184 {
00185         struct mnl_socket *nl;
00186         char buf[MNL_SOCKET_BUFFER_SIZE];
00187         struct nlmsghdr *nlh;
00188         struct genlmsghdr *genl;
00189         int ret;
00190         unsigned int seq, portid;
00191 
00192         if (argc != 2) {
00193                 printf("%s [family name]\n", argv[0]);
00194                 exit(EXIT_FAILURE);
00195         }
00196 
00197         nlh = mnl_nlmsg_put_header(buf);
00198         nlh->nlmsg_type = GENL_ID_CTRL;
00199         nlh->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK;
00200         nlh->nlmsg_seq = seq = time(NULL);
00201 
00202         genl = mnl_nlmsg_put_extra_header(nlh, sizeof(struct genlmsghdr));
00203         genl->cmd = CTRL_CMD_GETFAMILY;
00204         genl->version = 1;
00205 
00206         mnl_attr_put_u32(nlh, CTRL_ATTR_FAMILY_ID, GENL_ID_CTRL);
00207         mnl_attr_put_strz(nlh, CTRL_ATTR_FAMILY_NAME, argv[1]);
00208 
00209         nl = mnl_socket_open(NETLINK_GENERIC);
00210         if (nl == NULL) {
00211                 perror("mnl_socket_open");
00212                 exit(EXIT_FAILURE);
00213         }
00214 
00215         if (mnl_socket_bind(nl, 0, MNL_SOCKET_AUTOPID) < 0) {
00216                 perror("mnl_socket_bind");
00217                 exit(EXIT_FAILURE);
00218         }
00219         portid = mnl_socket_get_portid(nl);
00220 
00221         if (mnl_socket_sendto(nl, nlh, nlh->nlmsg_len) < 0) {
00222                 perror("mnl_socket_send");
00223                 exit(EXIT_FAILURE);
00224         }
00225 
00226         ret = mnl_socket_recvfrom(nl, buf, sizeof(buf));
00227         while (ret > 0) {
00228                 ret = mnl_cb_run(buf, ret, seq, portid, data_cb, NULL);
00229                 if (ret <= 0)
00230                         break;
00231                 ret = mnl_socket_recvfrom(nl, buf, sizeof(buf));
00232         }
00233         if (ret == -1) {
00234                 perror("error");
00235                 exit(EXIT_FAILURE);
00236         }
00237 
00238         mnl_socket_close(nl);
00239 
00240         return 0;
00241 }

Generated on Sun Dec 26 2010 22:23:55 for libmnl by  doxygen 1.7.1