}
int rtnl_message_read_internal(sd_rtnl_message *m, unsigned short type, void **data) {
+ struct rtattr *rta;
+
assert_return(m, -EINVAL);
assert_return(m->sealed, -EPERM);
assert_return(data, -EINVAL);
if(!m->rta_offset_tb[type])
return -ENODATA;
- *data = RTA_DATA((struct rtattr *)((uint8_t *) m->hdr + m->rta_offset_tb[type]));
+ rta = (struct rtattr*)((uint8_t *) m->hdr + m->rta_offset_tb[type]);
- return 0;
+ *data = RTA_DATA(rta);
+
+ return RTA_PAYLOAD(rta);
}
int sd_rtnl_message_read_string(sd_rtnl_message *m, unsigned short type, char **data) {
assert_return(data, -EINVAL);
r = rtnl_message_read_internal(m, type, &attr_data);
- if(r < 0)
+ if (r < 0)
return r;
+ else if (strnlen(attr_data, r) >= (size_t) r)
+ return -EIO;
*data = (char *) attr_data;
assert_return(data, -EINVAL);
r = rtnl_message_read_internal(m, type, &attr_data);
- if(r < 0)
+ if (r < 0)
return r;
+ else if ((size_t) r < sizeof(uint8_t))
+ return -EIO;
*data = *(uint8_t *) attr_data;
assert_return(data, -EINVAL);
r = rtnl_message_read_internal(m, type, &attr_data);
- if(r < 0)
+ if (r < 0)
return r;
+ else if ((size_t) r < sizeof(uint16_t))
+ return -EIO;
*data = *(uint16_t *) attr_data;
assert_return(data, -EINVAL);
r = rtnl_message_read_internal(m, type, &attr_data);
- if(r < 0)
+ if (r < 0)
return r;
+ else if ((size_t)r < sizeof(uint32_t))
+ return -EIO;
*data = *(uint32_t *) attr_data;
assert_return(data, -EINVAL);
r = rtnl_message_read_internal(m, type, &attr_data);
- if(r < 0)
+ if (r < 0)
return r;
+ else if ((size_t)r < sizeof(struct ether_addr))
+ return -EIO;
memcpy(data, attr_data, sizeof(struct ether_addr));
assert_return(data, -EINVAL);
r = rtnl_message_read_internal(m, type, &attr_data);
- if(r < 0)
+ if (r < 0)
return r;
+ else if ((size_t)r < sizeof(struct in_addr))
+ return -EIO;
memcpy(data, attr_data, sizeof(struct in_addr));