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; }
/* 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; }