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;
}
Ejemplo n.º 2
0
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;
}