msg_parse_attr.c

00001 int parse_message(struct nlmsghdr *hdr)
00002 {
00003         /*
00004          * The policy defines two attributes: a 32 bit integer and a container
00005          * for nested attributes.
00006          */
00007         struct nla_policy attr_policy[] = {
00008                 [ATTR_FOO] = { .type = NLA_U32 },
00009                 [ATTR_BAR] = { .type = NLA_NESTED },
00010         };
00011         struct nlattr *attrs[ATTR_MAX+1];
00012         int err;
00013 
00014         /*
00015          * The nlmsg_parse() function will make sure that the message contains
00016          * enough payload to hold the header (struct my_hdr), validates any
00017          * attributes attached to the messages and stores a pointer to each
00018          * attribute in the attrs[] array accessable by attribute type.
00019          */
00020         if ((err = nlmsg_parse(hdr, sizeof(struct my_hdr), attrs, ATTR_MAX,
00021                                attr_policy)) < 0)
00022                 goto errout;
00023 
00024         if (attrs[ATTR_FOO]) {
00025                 /*
00026                  * It is safe to directly access the attribute payload without
00027                  * any further checks since nlmsg_parse() enforced the policy.
00028                  */
00029                 uint32_t foo = nla_get_u32(attrs[ATTR_FOO]);
00030         }
00031 
00032         if (attrs[ATTR_BAR]) {
00033                 struct *nested[NESTED_MAX+1];
00034 
00035                 /*
00036                  * Attributes nested in a container can be parsed the same way
00037                  * as top level attributes.
00038                  */
00039                 err = nla_parse_nested(nested, NESTED_MAX, attrs[ATTR_BAR],
00040                                        nested_policy);
00041                 if (err < 0)
00042                         goto errout;
00043 
00044                 // Process nested attributes here.
00045         }
00046 
00047         err = 0;
00048 errout:
00049         return err;
00050 }