int cthd_nl_wrapper::genl_get_mcast_group_id(struct nlmsghdr *n)
{
        struct rtattr *tb[CTRL_ATTR_MAX + 1];
        struct genlmsghdr *ghdr = (struct genlmsghdr *)NLMSG_DATA(n);
        int len = n->nlmsg_len;
        struct rtattr *attrs;
	__u32 ctrl_v = 0x1;

        if (n->nlmsg_type != GENL_ID_CTRL) {
                fprintf(stderr, "Not a controller message, nlmsg_len=%d "
                        "nlmsg_type=0x%x\n", n->nlmsg_len, n->nlmsg_type);
                return 0;
        }

        if (ghdr->cmd != CTRL_CMD_GETFAMILY &&
            ghdr->cmd != CTRL_CMD_DELFAMILY &&
            ghdr->cmd != CTRL_CMD_NEWFAMILY &&
            ghdr->cmd != CTRL_CMD_NEWMCAST_GRP &&
            ghdr->cmd != CTRL_CMD_DELMCAST_GRP) {
                fprintf(stderr, "Unkown controller command %d\n", ghdr->cmd);
                return 0;
        }

        len -= NLMSG_LENGTH(GENL_HDRLEN);

        if (len < 0) {
                fprintf(stderr, "wrong controller message len %d\n", len);
                return -1;
        }

        attrs = (struct rtattr *)((char *)ghdr + GENL_HDRLEN);
        parse_rtattr(tb, CTRL_ATTR_MAX, attrs, len);

	if (tb[CTRL_ATTR_FAMILY_ID])
		acpi_event_family_id =
			*((__u32 *)RTA_DATA(tb[CTRL_ATTR_FAMILY_ID]));

        if (tb[CTRL_ATTR_MCAST_GROUPS]) {
                struct rtattr *tb2[GENL_MAX_FAM_GRPS + 1];
                int i;

                parse_rtattr_nested(tb2, GENL_MAX_FAM_GRPS,
                                        tb[CTRL_ATTR_MCAST_GROUPS]);

                for (i = 0; i < GENL_MAX_FAM_GRPS; i++)
                        if (tb2[i])
                                if (!get_ctrl_grp_id(tb2[i]))
        				return 0;
	}

        return -1;
}
Esempio n. 2
0
/* n = the response to a CTRL_CMD_GETFAMILY message */
static int
genl_get_mcast_group_id(struct nlmsghdr *n)
{
	/*
	 *  Attribute table.  Note the type name "rtattr" which means "route
	 *  attribute".  This is a vestige of one of netlink's main uses:
	 *  routing.
	 */
	struct rtattr *tb[CTRL_ATTR_MAX + 1];
	/* place for the generic netlink header in the incoming message */
	struct genlmsghdr ghdr;
	/* length of the attribute and payload */
	int len = n->nlmsg_len - NLMSG_LENGTH(GENL_HDRLEN);
	/* Pointer to the attribute portion of the message */
	struct rtattr *attrs;

	if (len < 0) {
		printf("Netlink: CTRL_CMD_GETFAMILY response, "
			"wrong controller message len: %d\n", len);
		return -1;
	}

	if (n->nlmsg_type != GENL_ID_CTRL) {
		printf("Netlink: Not a controller message, nlmsg_len=%d "
			"nlmsg_type=0x%x\n", n->nlmsg_len, n->nlmsg_type);
		return 0;
	}

	/* copy generic netlink header into structure */
	memcpy(&ghdr, NLMSG_DATA(n), GENL_HDRLEN);

	if (ghdr.cmd != CTRL_CMD_GETFAMILY &&
	    ghdr.cmd != CTRL_CMD_DELFAMILY &&
	    ghdr.cmd != CTRL_CMD_NEWFAMILY &&
	    ghdr.cmd != CTRL_CMD_NEWMCAST_GRP &&
	    ghdr.cmd != CTRL_CMD_DELMCAST_GRP) {
		printf("Netlink: Unknown controller command %d\n", ghdr.cmd);
		return 0;
	}

	/* set attrs to point to the attribute */
	attrs = (struct rtattr *)(NLMSG_DATA(n) + GENL_HDRLEN);
	/* Read the table from the message into "tb".  This actually just  */
	/* places pointers into the message into tb[].  */
	parse_rtattr(tb, CTRL_ATTR_MAX, attrs, len);

	/* if a family ID attribute is present, get it */
	if (tb[CTRL_ATTR_FAMILY_ID])
	{
		acpi_event_family_id =
			*((__u32 *)RTA_DATA(tb[CTRL_ATTR_FAMILY_ID]));
	}

	/* if a "multicast groups" attribute is present... */
	if (tb[CTRL_ATTR_MCAST_GROUPS]) {
		struct rtattr *tb2[GENL_MAX_FAM_GRPS + 1];
		int i;

		/* get the group table within this attribute  */
		parse_rtattr_nested(tb2, GENL_MAX_FAM_GRPS,
			tb[CTRL_ATTR_MCAST_GROUPS]);

		/* for each group */
		for (i = 0; i < GENL_MAX_FAM_GRPS; i++)
			/* if this group is valid */
			if (tb2[i])
				/* Parse the ID.  If successful, we're done. */
				if (!get_ctrl_grp_id(tb2[i]))
					return 0;
	}

	return -1;
}