int cthd_nl_wrapper::genl_get_family_status(char *family_name, int type) { struct rtnl_handle rth; struct nlmsghdr *nlh; struct genlmsghdr *ghdr; int ret = -1; struct { struct nlmsghdr n; char buf[4096]; } req; memset(&req, 0, sizeof(req)); nlh = &req.n; nlh->nlmsg_len = NLMSG_LENGTH(GENL_HDRLEN); nlh->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK; nlh->nlmsg_type = GENL_ID_CTRL; ghdr = (struct genlmsghdr *)NLMSG_DATA(&req.n); ghdr->cmd = CTRL_CMD_GETFAMILY; /* send CTRL_CMD_GET_FAMILY message to controller */ if (rtnl_open_byproto(&rth, 0, NETLINK_GENERIC) < 0) { fprintf(stderr, "Cannot open generic netlink socket\n"); exit(1); } addattr_l(nlh, 128, CTRL_ATTR_FAMILY_NAME, family_name, strlen(family_name) + 1); if (rtnl_talk(&rth, nlh, 0, 0, nlh, NULL, NULL) < 0) { fprintf(stderr, "Error talking to the kernel\n"); goto ctrl_done; } if (type) { if (genl_get_mcast_group_id(nlh)) fprintf(stderr, "Failed to get acpi_event multicast group\n"); } else if (genl_print_ctrl_message(NULL, nlh, (void *)stdout) < 0) fprintf(stderr, "Failed to print acpi_event family status\n"); ret = 0; ctrl_done: rtnl_close(&rth); return ret; }
static int genl_get_ids(char *family_name) { /* handle to the netlink connection */ struct rtnl_handle rth; /* holds the request we are going to send and the reply */ struct { struct nlmsghdr n; char buf[4096]; /* ??? Is this big enough for all cases? */ } req; /* pointer to the nlmsghdr in req */ struct nlmsghdr *nlh; /* place for the generic netlink header before copied into req */ struct genlmsghdr ghdr; /* return value */ int ret = -1; /* clear out the request */ memset(&req, 0, sizeof(req)); /* set up nlh to point to the netlink header in req */ nlh = &req.n; /* set up the netlink header */ nlh->nlmsg_len = NLMSG_LENGTH(GENL_HDRLEN); nlh->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK; nlh->nlmsg_type = GENL_ID_CTRL; /* clear out the generic netlink message header */ memset(&ghdr, 0, sizeof(struct genlmsghdr)); /* set the command we want to run: "GETFAMILY" */ ghdr.cmd = CTRL_CMD_GETFAMILY; /* copy it into req */ memcpy(NLMSG_DATA(&req.n), &ghdr, GENL_HDRLEN); /* the message payload is the family name */ addattr_l(nlh, 128, CTRL_ATTR_FAMILY_NAME, family_name, strlen(family_name) + 1); /* open a generic netlink connection */ if (rtnl_open_byproto(&rth, 0, NETLINK_GENERIC) < 0) { printf("Netlink: Cannot open generic netlink socket\n"); return -1; } /* * Send CTRL_CMD_GETFAMILY message (in nlh) to the generic * netlink controller. Reply will be in nlh upon return. */ if (rtnl_talk(&rth, nlh, 0, 0, nlh, NULL, NULL) < 0) { printf("Netlink: Error talking to the kernel\n"); goto ctrl_done; } /* process the response */ if (genl_get_mcast_group_id(nlh) < 0) { printf("Netlink: Failed to get acpi_event multicast group\n"); goto ctrl_done; } ret = 0; ctrl_done: rtnl_close(&rth); return ret; }