+ r = rtnl_message_read_internal(m, type, &attr_data);
+ if (r < 0)
+ return r;
+ else if (strnlen(attr_data, r) >= (size_t) r)
+ return -EIO;
+
+ *data = (char *) attr_data;
+
+ return 0;
+}
+
+int sd_rtnl_message_read_u8(sd_rtnl_message *m, unsigned short type, uint8_t *data) {
+ int r;
+ void *attr_data;
+
+ r = message_attribute_has_type(m, type, NLA_U8);
+ if (r < 0)
+ return r;
+
+ r = rtnl_message_read_internal(m, type, &attr_data);
+ if (r < 0)
+ return r;
+ else if ((size_t) r < sizeof(uint8_t))
+ return -EIO;
+
+ *data = *(uint8_t *) attr_data;
+
+ return 0;
+}
+
+int sd_rtnl_message_read_u16(sd_rtnl_message *m, unsigned short type, uint16_t *data) {
+ int r;
+ void *attr_data;
+
+ r = message_attribute_has_type(m, type, NLA_U16);
+ if (r < 0)
+ return r;
+
+ r = rtnl_message_read_internal(m, type, &attr_data);
+ if (r < 0)
+ return r;
+ else if ((size_t) r < sizeof(uint16_t))
+ return -EIO;
+
+ *data = *(uint16_t *) attr_data;
+
+ return 0;
+}
+
+int sd_rtnl_message_read_u32(sd_rtnl_message *m, unsigned short type, uint32_t *data) {
+ int r;
+ void *attr_data;
+
+ r = message_attribute_has_type(m, type, NLA_U32);
+ if (r < 0)
+ return r;
+
+ r = rtnl_message_read_internal(m, type, &attr_data);
+ if (r < 0)
+ return r;
+ else if ((size_t)r < sizeof(uint32_t))
+ return -EIO;
+
+ *data = *(uint32_t *) attr_data;
+
+ return 0;
+}
+
+int sd_rtnl_message_read_ether_addr(sd_rtnl_message *m, unsigned short type, struct ether_addr *data) {
+ int r;
+ void *attr_data;
+
+ r = message_attribute_has_type(m, type, NLA_ETHER_ADDR);
+ if (r < 0)
+ return r;
+
+ r = rtnl_message_read_internal(m, type, &attr_data);
+ if (r < 0)
+ return r;
+ else if ((size_t)r < sizeof(struct ether_addr))
+ return -EIO;
+
+ memcpy(data, attr_data, sizeof(struct ether_addr));
+
+ return 0;
+}
+
+int sd_rtnl_message_read_cache_info(sd_rtnl_message *m, unsigned short type, struct ifa_cacheinfo *info) {
+ int r;
+ void *attr_data;
+
+ r = message_attribute_has_type(m, type, NLA_CACHE_INFO);
+ if (r < 0)
+ return r;
+
+ r = rtnl_message_read_internal(m, type, &attr_data);
+ if (r < 0)
+ return r;
+ else if ((size_t)r < sizeof(struct ifa_cacheinfo))
+ return -EIO;
+
+ memcpy(info, attr_data, sizeof(struct ifa_cacheinfo));
+
+ return 0;
+}
+
+int sd_rtnl_message_read_in_addr(sd_rtnl_message *m, unsigned short type, struct in_addr *data) {
+ int r;
+ void *attr_data;
+
+ r = message_attribute_has_type(m, type, NLA_IN_ADDR);
+ if (r < 0)
+ return r;
+
+ r = rtnl_message_read_internal(m, type, &attr_data);
+ if (r < 0)
+ return r;
+ else if ((size_t)r < sizeof(struct in_addr))
+ return -EIO;
+
+ memcpy(data, attr_data, sizeof(struct in_addr));
+
+ return 0;
+}
+
+int sd_rtnl_message_read_in6_addr(sd_rtnl_message *m, unsigned short type, struct in6_addr *data) {
+ int r;
+ void *attr_data;
+
+ r = message_attribute_has_type(m, type, NLA_IN_ADDR);
+ if (r < 0)
+ return r;
+
+ r = rtnl_message_read_internal(m, type, &attr_data);
+ if (r < 0)
+ return r;
+ else if ((size_t)r < sizeof(struct in6_addr))
+ return -EIO;
+
+ memcpy(data, attr_data, sizeof(struct in6_addr));
+
+ return 0;
+}
+
+int sd_rtnl_message_enter_container(sd_rtnl_message *m, unsigned short type) {
+ const NLType *nl_type;
+ const NLTypeSystem *type_system;
+ void *container;
+ size_t size;
+ int r;
+
+ assert_return(m, -EINVAL);
+ assert_return(m->n_containers < RTNL_CONTAINER_DEPTH, -EINVAL);
+
+ r = type_system_get_type(m->container_type_system[m->n_containers],
+ &nl_type,
+ type);
+ if (r < 0)
+ return r;
+
+ if (nl_type->type == NLA_NESTED) {
+ r = type_system_get_type_system(m->container_type_system[m->n_containers],
+ &type_system,
+ type);
+ if (r < 0)
+ return r;
+ } else if (nl_type->type == NLA_UNION) {
+ const NLTypeSystemUnion *type_system_union;
+ char *key;
+
+ r = type_system_get_type_system_union(m->container_type_system[m->n_containers],
+ &type_system_union,
+ type);
+ if (r < 0)
+ return r;
+
+ r = sd_rtnl_message_read_string(m, type_system_union->match, &key);
+ if (r < 0)
+ return r;
+
+ r = type_system_union_get_type_system(type_system_union,
+ &type_system,
+ key);
+ if (r < 0)
+ return r;
+ } else
+ return -EINVAL;
+
+ r = rtnl_message_read_internal(m, type, &container);
+ if (r < 0)
+ return r;
+ else
+ size = (size_t)r;
+
+ m->n_containers ++;
+
+ r = rtnl_message_parse(m,
+ &m->rta_offset_tb[m->n_containers],
+ &m->rta_tb_size[m->n_containers],
+ type_system->max,
+ container,
+ size);
+ if (r < 0) {
+ m->n_containers --;
+ return r;