ctrl.c revision 26328fc3933f377c47fb8b06feabbde5e12ed650
165018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim/* 265018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim * ctrl.c generic netlink controller 365018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim * 465018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim * This program is free software; you can distribute it and/or 565018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim * modify it under the terms of the GNU General Public License 665018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim * as published by the Free Software Foundation; either version 765018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim * 2 of the License, or (at your option) any later version. 865018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim * 965018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim * Authors: J Hadi Salim (hadi@cyberus.ca) 1065018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim */ 1165018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim 1265018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim#include <stdio.h> 1365018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim#include <stdlib.h> 1465018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim#include <unistd.h> 1565018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim#include <syslog.h> 1665018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim#include <fcntl.h> 1765018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim#include <sys/socket.h> 1865018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim#include <netinet/in.h> 1965018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim#include <arpa/inet.h> 2065018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim#include <string.h> 2165018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim 2265018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim#include "utils.h" 2365018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim#include "genl_utils.h" 2465018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim 2526328fc3933f377c47fb8b06feabbde5e12ed650jamal#define GENL_MAX_FAM_OPS 256 2665018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salimstatic int usage(void) 2765018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim{ 2865018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim fprintf(stderr,"Usage: ctrl <CMD>\n" \ 2965018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim "CMD := get <PARMS> | list | monitor\n" \ 3065018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim "PARMS := name <name> | id <id>\n" \ 3165018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim "Examples:\n" \ 3265018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim "\tctrl ls\n" \ 3365018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim "\tctrl monitor\n" \ 3465018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim "\tctrl get name foobar\n" \ 3565018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim "\tctrl get id 0xF\n"); 3665018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim return -1; 3765018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim} 3865018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim 3965018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salimint genl_ctrl_resolve_family(const char *family) 4065018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim{ 4165018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim struct rtnl_handle rth; 4265018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim struct nlmsghdr *nlh; 4365018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim struct genlmsghdr *ghdr; 4465018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim int ret = 0; 4565018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim struct { 4665018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim struct nlmsghdr n; 4765018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim char buf[4096]; 4865018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim } req; 4965018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim 5065018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim memset(&req, 0, sizeof(req)); 5165018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim 5265018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim nlh = &req.n; 5365018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim nlh->nlmsg_len = NLMSG_LENGTH(GENL_HDRLEN); 5465018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim nlh->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK; 5565018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim nlh->nlmsg_type = GENL_ID_CTRL; 5665018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim 5765018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim ghdr = NLMSG_DATA(&req.n); 5865018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim ghdr->cmd = CTRL_CMD_GETFAMILY; 5965018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim 6065018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim if (rtnl_open_byproto(&rth, 0, NETLINK_GENERIC) < 0) { 6165018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim fprintf(stderr, "Cannot open generic netlink socket\n"); 6265018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim exit(1); 6365018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim } 6465018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim 6565018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim addattr_l(nlh, 128, CTRL_ATTR_FAMILY_NAME, family, strlen(family) + 1); 6665018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim 6765018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim if (rtnl_talk(&rth, nlh, 0, 0, nlh, NULL, NULL) < 0) { 6865018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim fprintf(stderr, "Error talking to the kernel\n"); 6965018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim goto errout; 7065018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim } 7165018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim 7265018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim { 7365018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim struct rtattr *tb[CTRL_ATTR_MAX + 1]; 7465018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim struct genlmsghdr *ghdr = NLMSG_DATA(nlh); 7565018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim int len = nlh->nlmsg_len; 7665018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim struct rtattr *attrs; 7765018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim 7865018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim if (nlh->nlmsg_type != GENL_ID_CTRL) { 7965018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim fprintf(stderr, "Not a controller message, nlmsg_len=%d " 8065018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim "nlmsg_type=0x%x\n", nlh->nlmsg_len, nlh->nlmsg_type); 8165018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim goto errout; 8265018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim } 8365018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim 8465018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim if (ghdr->cmd != CTRL_CMD_NEWFAMILY) { 8565018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim fprintf(stderr, "Unkown controller command %d\n", ghdr->cmd); 8665018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim goto errout; 8765018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim } 8865018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim 8965018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim len -= NLMSG_LENGTH(GENL_HDRLEN); 9065018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim 9165018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim if (len < 0) { 9265018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim fprintf(stderr, "wrong controller message len %d\n", len); 9365018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim return -1; 9465018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim } 9565018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim 9665018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim attrs = (struct rtattr *) ((char *) ghdr + GENL_HDRLEN); 9765018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim parse_rtattr(tb, CTRL_ATTR_MAX, attrs, len); 9865018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim 9965018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim if (tb[CTRL_ATTR_FAMILY_ID] == NULL) { 10065018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim fprintf(stderr, "Missing family id TLV\n"); 10165018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim goto errout; 10265018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim } 10365018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim 10465018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim ret = *(__u16 *) RTA_DATA(tb[CTRL_ATTR_FAMILY_ID]); 10565018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim } 10665018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim 10765018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salimerrout: 10865018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim rtnl_close(&rth); 10965018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim return ret; 11065018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim} 11165018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim 11226328fc3933f377c47fb8b06feabbde5e12ed650jamalvoid print_ctrl_cmd_flags(FILE *fp, __u32 fl) 11326328fc3933f377c47fb8b06feabbde5e12ed650jamal{ 11426328fc3933f377c47fb8b06feabbde5e12ed650jamal fprintf(fp, "\n\t\tCapabilities (0x%x):\n ", fl); 11526328fc3933f377c47fb8b06feabbde5e12ed650jamal if (!fl) { 11626328fc3933f377c47fb8b06feabbde5e12ed650jamal fprintf(fp, "\n"); 11726328fc3933f377c47fb8b06feabbde5e12ed650jamal return; 11826328fc3933f377c47fb8b06feabbde5e12ed650jamal } 11926328fc3933f377c47fb8b06feabbde5e12ed650jamal fprintf(fp, "\t\t "); 12026328fc3933f377c47fb8b06feabbde5e12ed650jamal 12126328fc3933f377c47fb8b06feabbde5e12ed650jamal if (fl & GENL_ADMIN_PERM) 12226328fc3933f377c47fb8b06feabbde5e12ed650jamal fprintf(fp, " requires admin permission;"); 12326328fc3933f377c47fb8b06feabbde5e12ed650jamal if (fl & GENL_CMD_CAP_DO) 12426328fc3933f377c47fb8b06feabbde5e12ed650jamal fprintf(fp, " can doit;"); 12526328fc3933f377c47fb8b06feabbde5e12ed650jamal if (fl & GENL_CMD_CAP_DUMP) 12626328fc3933f377c47fb8b06feabbde5e12ed650jamal fprintf(fp, " can dumpit;"); 12726328fc3933f377c47fb8b06feabbde5e12ed650jamal if (fl & GENL_CMD_CAP_HASPOL) 12826328fc3933f377c47fb8b06feabbde5e12ed650jamal fprintf(fp, " has policy"); 12926328fc3933f377c47fb8b06feabbde5e12ed650jamal 13026328fc3933f377c47fb8b06feabbde5e12ed650jamal fprintf(fp, "\n"); 13126328fc3933f377c47fb8b06feabbde5e12ed650jamal} 13226328fc3933f377c47fb8b06feabbde5e12ed650jamal 13326328fc3933f377c47fb8b06feabbde5e12ed650jamalstatic int print_ctrl_cmds(FILE *fp, struct rtattr *arg, __u32 ctrl_ver) 13426328fc3933f377c47fb8b06feabbde5e12ed650jamal{ 13526328fc3933f377c47fb8b06feabbde5e12ed650jamal struct rtattr *tb[CTRL_ATTR_OP_MAX + 1]; 13626328fc3933f377c47fb8b06feabbde5e12ed650jamal 13726328fc3933f377c47fb8b06feabbde5e12ed650jamal if (arg == NULL) 13826328fc3933f377c47fb8b06feabbde5e12ed650jamal return -1; 13926328fc3933f377c47fb8b06feabbde5e12ed650jamal 14026328fc3933f377c47fb8b06feabbde5e12ed650jamal parse_rtattr_nested(tb, CTRL_ATTR_OP_MAX, arg); 14126328fc3933f377c47fb8b06feabbde5e12ed650jamal if (tb[CTRL_ATTR_OP_ID]) { 14226328fc3933f377c47fb8b06feabbde5e12ed650jamal __u32 *id = RTA_DATA(tb[CTRL_ATTR_OP_ID]); 14326328fc3933f377c47fb8b06feabbde5e12ed650jamal fprintf(fp, " ID-0x%x ",*id); 14426328fc3933f377c47fb8b06feabbde5e12ed650jamal } 14526328fc3933f377c47fb8b06feabbde5e12ed650jamal /* we are only gonna do this for newer version of the controller */ 14626328fc3933f377c47fb8b06feabbde5e12ed650jamal if (tb[CTRL_ATTR_OP_FLAGS] && ctrl_ver >= 0x2) { 14726328fc3933f377c47fb8b06feabbde5e12ed650jamal __u32 *fl = RTA_DATA(tb[CTRL_ATTR_OP_FLAGS]); 14826328fc3933f377c47fb8b06feabbde5e12ed650jamal print_ctrl_cmd_flags(fp, *fl); 14926328fc3933f377c47fb8b06feabbde5e12ed650jamal } 15026328fc3933f377c47fb8b06feabbde5e12ed650jamal return 0; 15126328fc3933f377c47fb8b06feabbde5e12ed650jamal 15226328fc3933f377c47fb8b06feabbde5e12ed650jamal} 15326328fc3933f377c47fb8b06feabbde5e12ed650jamal 15426328fc3933f377c47fb8b06feabbde5e12ed650jamal/* 15526328fc3933f377c47fb8b06feabbde5e12ed650jamal * The controller sends one nlmsg per family 15626328fc3933f377c47fb8b06feabbde5e12ed650jamal*/ 15765018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salimstatic int print_ctrl(const struct sockaddr_nl *who, struct nlmsghdr *n, 15865018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim void *arg) 15965018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim{ 16065018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim struct rtattr *tb[CTRL_ATTR_MAX + 1]; 16165018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim struct genlmsghdr *ghdr = NLMSG_DATA(n); 16265018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim int len = n->nlmsg_len; 16365018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim struct rtattr *attrs; 16465018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim FILE *fp = (FILE *) arg; 16526328fc3933f377c47fb8b06feabbde5e12ed650jamal __u32 ctrl_v = 0x1; 16665018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim 16765018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim if (n->nlmsg_type != GENL_ID_CTRL) { 16865018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim fprintf(stderr, "Not a controller message, nlmsg_len=%d " 16965018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim "nlmsg_type=0x%x\n", n->nlmsg_len, n->nlmsg_type); 17065018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim return 0; 17165018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim } 17265018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim 17365018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim if (ghdr->cmd != CTRL_CMD_GETFAMILY && 17465018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim ghdr->cmd != CTRL_CMD_DELFAMILY && 17565018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim ghdr->cmd != CTRL_CMD_NEWFAMILY) { 17665018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim fprintf(stderr, "Unkown controller command %d\n", ghdr->cmd); 17765018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim return 0; 17865018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim } 17965018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim 18065018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim len -= NLMSG_LENGTH(GENL_HDRLEN); 18165018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim 18265018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim if (len < 0) { 18365018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim fprintf(stderr, "wrong controller message len %d\n", len); 18465018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim return -1; 18565018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim } 18665018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim 18765018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim attrs = (struct rtattr *) ((char *) ghdr + GENL_HDRLEN); 18865018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim parse_rtattr(tb, CTRL_ATTR_MAX, attrs, len); 18965018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim 19065018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim if (tb[CTRL_ATTR_FAMILY_NAME]) { 19165018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim char *name = RTA_DATA(tb[CTRL_ATTR_FAMILY_NAME]); 19226328fc3933f377c47fb8b06feabbde5e12ed650jamal fprintf(fp, "\nName: %s\n",name); 19365018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim } 19465018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim if (tb[CTRL_ATTR_FAMILY_ID]) { 19565018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim __u16 *id = RTA_DATA(tb[CTRL_ATTR_FAMILY_ID]); 19626328fc3933f377c47fb8b06feabbde5e12ed650jamal fprintf(fp, "\tID: 0x%x ",*id); 19726328fc3933f377c47fb8b06feabbde5e12ed650jamal } 19826328fc3933f377c47fb8b06feabbde5e12ed650jamal if (tb[CTRL_ATTR_VERSION]) { 19926328fc3933f377c47fb8b06feabbde5e12ed650jamal __u32 *v = RTA_DATA(tb[CTRL_ATTR_VERSION]); 20026328fc3933f377c47fb8b06feabbde5e12ed650jamal fprintf(fp, " Version: 0x%x ",*v); 20126328fc3933f377c47fb8b06feabbde5e12ed650jamal ctrl_v = *v; 20265018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim } 20326328fc3933f377c47fb8b06feabbde5e12ed650jamal if (tb[CTRL_ATTR_HDRSIZE]) { 20426328fc3933f377c47fb8b06feabbde5e12ed650jamal __u32 *h = RTA_DATA(tb[CTRL_ATTR_HDRSIZE]); 20526328fc3933f377c47fb8b06feabbde5e12ed650jamal fprintf(fp, " header size: %d ",*h); 20626328fc3933f377c47fb8b06feabbde5e12ed650jamal } 20726328fc3933f377c47fb8b06feabbde5e12ed650jamal if (tb[CTRL_ATTR_MAXATTR]) { 20826328fc3933f377c47fb8b06feabbde5e12ed650jamal __u32 *ma = RTA_DATA(tb[CTRL_ATTR_MAXATTR]); 20926328fc3933f377c47fb8b06feabbde5e12ed650jamal fprintf(fp, " max attribs: %d ",*ma); 21026328fc3933f377c47fb8b06feabbde5e12ed650jamal } 21126328fc3933f377c47fb8b06feabbde5e12ed650jamal /* end of family definitions .. */ 21226328fc3933f377c47fb8b06feabbde5e12ed650jamal fprintf(fp,"\n"); 21326328fc3933f377c47fb8b06feabbde5e12ed650jamal if (tb[CTRL_ATTR_OPS]) { 21426328fc3933f377c47fb8b06feabbde5e12ed650jamal struct rtattr *tb2[GENL_MAX_FAM_OPS]; 21526328fc3933f377c47fb8b06feabbde5e12ed650jamal int i=0; 21626328fc3933f377c47fb8b06feabbde5e12ed650jamal parse_rtattr_nested(tb2, GENL_MAX_FAM_OPS, tb[CTRL_ATTR_OPS]); 21726328fc3933f377c47fb8b06feabbde5e12ed650jamal fprintf(fp, "\tcommands supported: \n"); 21826328fc3933f377c47fb8b06feabbde5e12ed650jamal for (i = 0; i < GENL_MAX_FAM_OPS; i++) { 21926328fc3933f377c47fb8b06feabbde5e12ed650jamal if (tb2[i]) { 22026328fc3933f377c47fb8b06feabbde5e12ed650jamal fprintf(fp, "\t\t#%d: ", i); 22126328fc3933f377c47fb8b06feabbde5e12ed650jamal if (0 > print_ctrl_cmds(fp, tb2[i], ctrl_v)) { 22226328fc3933f377c47fb8b06feabbde5e12ed650jamal fprintf(fp, "Error printing command\n"); 22326328fc3933f377c47fb8b06feabbde5e12ed650jamal } 22426328fc3933f377c47fb8b06feabbde5e12ed650jamal /* for next command */ 22526328fc3933f377c47fb8b06feabbde5e12ed650jamal fprintf(fp,"\n"); 22626328fc3933f377c47fb8b06feabbde5e12ed650jamal } 22726328fc3933f377c47fb8b06feabbde5e12ed650jamal } 22865018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim 22926328fc3933f377c47fb8b06feabbde5e12ed650jamal /* end of family::cmds definitions .. */ 23026328fc3933f377c47fb8b06feabbde5e12ed650jamal fprintf(fp,"\n"); 23126328fc3933f377c47fb8b06feabbde5e12ed650jamal } 23265018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim fflush(fp); 23365018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim return 0; 23465018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim} 23565018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim 23665018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salimstatic int ctrl_list(int cmd, int argc, char **argv) 23765018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim{ 23865018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim struct rtnl_handle rth; 23965018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim struct nlmsghdr *nlh; 24065018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim struct genlmsghdr *ghdr; 24165018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim int ret = -1; 24265018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim char d[GENL_NAMSIZ]; 24365018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim struct { 24465018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim struct nlmsghdr n; 24565018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim char buf[4096]; 24665018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim } req; 24765018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim 24865018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim memset(&req, 0, sizeof(req)); 24965018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim 25065018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim nlh = &req.n; 25165018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim nlh->nlmsg_len = NLMSG_LENGTH(GENL_HDRLEN); 25265018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim nlh->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK; 25365018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim nlh->nlmsg_type = GENL_ID_CTRL; 25465018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim 25565018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim ghdr = NLMSG_DATA(&req.n); 25665018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim ghdr->cmd = CTRL_CMD_GETFAMILY; 25765018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim 25865018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim if (rtnl_open_byproto(&rth, 0, NETLINK_GENERIC) < 0) { 25965018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim fprintf(stderr, "Cannot open generic netlink socket\n"); 26065018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim exit(1); 26165018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim } 26265018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim 26365018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim if (cmd == CTRL_CMD_GETFAMILY) { 26465018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim if (argc != 2) { 26565018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim fprintf(stderr, "Wrong number of params\n"); 26665018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim return -1; 26765018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim } 26865018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim 26965018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim if (matches(*argv, "name") == 0) { 27065018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim NEXT_ARG(); 27165018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim strncpy(d, *argv, sizeof (d) - 1); 27265018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim addattr_l(nlh, 128, CTRL_ATTR_FAMILY_NAME, 27365018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim d, strlen(d) + 1); 27465018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim } else if (matches(*argv, "id") == 0) { 27565018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim __u16 id; 27665018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim NEXT_ARG(); 27765018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim if (get_u16(&id, *argv, 0)) { 27865018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim fprintf(stderr, "Illegal \"id\"\n"); 27965018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim goto ctrl_done; 28065018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim } 28165018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim 28265018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim addattr_l(nlh, 128, CTRL_ATTR_FAMILY_ID, &id, 2); 28365018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim 28465018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim } else { 28565018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim fprintf(stderr, "Wrong params\n"); 28665018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim goto ctrl_done; 28765018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim } 28865018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim 28965018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim if (rtnl_talk(&rth, nlh, 0, 0, nlh, NULL, NULL) < 0) { 29065018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim fprintf(stderr, "Error talking to the kernel\n"); 29165018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim goto ctrl_done; 29265018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim } 29365018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim 29465018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim if (print_ctrl(NULL, nlh, (void *) stdout) < 0) { 29565018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim fprintf(stderr, "Dump terminated\n"); 29665018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim goto ctrl_done; 29765018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim } 29865018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim 29965018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim } 30065018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim 30165018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim if (cmd == CTRL_CMD_UNSPEC) { 30265018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim nlh->nlmsg_flags = NLM_F_ROOT|NLM_F_MATCH|NLM_F_REQUEST; 30365018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim nlh->nlmsg_seq = rth.dump = ++rth.seq; 30465018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim 30565018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim if (rtnl_send(&rth, (const char *) nlh, nlh->nlmsg_len) < 0) { 30665018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim perror("Failed to send dump request\n"); 30765018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim goto ctrl_done; 30865018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim } 30965018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim 31065018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim rtnl_dump_filter(&rth, print_ctrl, stdout, NULL, NULL); 31165018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim 31265018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim } 31365018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim 31465018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim ret = 0; 31565018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salimctrl_done: 31665018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim rtnl_close(&rth); 31765018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim return ret; 31865018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim} 31965018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim 32065018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salimstatic int ctrl_listen(int argc, char **argv) 32165018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim{ 32265018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim struct rtnl_handle rth; 32365018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim 32465018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim if (rtnl_open_byproto(&rth, nl_mgrp(GENL_ID_CTRL), NETLINK_GENERIC) < 0) { 32565018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim fprintf(stderr, "Canot open generic netlink socket\n"); 32665018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim return -1; 32765018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim } 32865018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim 32965018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim if (rtnl_listen(&rth, print_ctrl, (void *) stdout) < 0) 33065018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim return -1; 33165018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim 33265018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim return 0; 33365018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim} 33465018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim 33565018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salimstatic int parse_ctrl(struct genl_util *a, int argc, char **argv) 33665018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim{ 33765018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim argv++; 33865018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim if (--argc <= 0) { 33965018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim fprintf(stderr, "wrong controller params\n"); 34065018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim return -1; 34165018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim } 34265018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim 34365018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim if (matches(*argv, "monitor") == 0) 34465018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim return ctrl_listen(argc-1, argv+1); 34565018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim if (matches(*argv, "get") == 0) 34665018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim return ctrl_list(CTRL_CMD_GETFAMILY, argc-1, argv+1); 34765018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim if (matches(*argv, "list") == 0 || 34865018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim matches(*argv, "show") == 0 || 34965018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim matches(*argv, "lst") == 0) 35065018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim return ctrl_list(CTRL_CMD_UNSPEC, argc-1, argv+1); 35165018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim if (matches(*argv, "help") == 0) 35265018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim return usage(); 35365018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim 35465018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim fprintf(stderr, "ctrl command \"%s\" is unknown, try \"ctrl -help\".\n", 35565018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim *argv); 35665018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim 35765018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim return -1; 35865018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim} 35965018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim 36065018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salimstruct genl_util ctrl_genl_util = { 36165018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim .name = "ctrl", 36265018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim .parse_genlopt = parse_ctrl, 36365018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim .print_genlopt = print_ctrl, 36465018ae43b14c8157bbe05473d76635626177b87Jamal Hadi Salim}; 365