int rtnl_send(struct rtnl_handle *rth, const char *buf, int len)
{
struct sockaddr_nl nladdr;
+ struct nlmsghdr *h;
+ int status;
+ char resp[1024];
memset(&nladdr, 0, sizeof(nladdr));
nladdr.nl_family = AF_NETLINK;
- return sendto(rth->fd, buf, len, 0, (struct sockaddr*)&nladdr, sizeof(nladdr));
+ status = sendto(rth->fd, buf, len, 0,
+ (struct sockaddr*)&nladdr, sizeof(nladdr));
+ if (status < 0)
+ return status;
+
+ /* Check for errors */
+ status = recv(rth->fd, resp, sizeof(resp), MSG_DONTWAIT);
+ if (status < 0) {
+ if (errno == EAGAIN)
+ return 0;
+ return -1;
+ }
+
+ for (h = (struct nlmsghdr *)resp; NLMSG_OK(h, status);
+ h = NLMSG_NEXT(h, status)) {
+ if (h->nlmsg_type == NLMSG_ERROR) {
+ struct nlmsgerr *err = (struct nlmsgerr*)NLMSG_DATA(h);
+ if (h->nlmsg_len < NLMSG_LENGTH(sizeof(struct nlmsgerr)))
+ fprintf(stderr, "ERROR truncated\n");
+ else
+ errno = -err->error;
+ }
+ return -1;
+ }
+
+ return 0;
}
int rtnl_dump_request(struct rtnl_handle *rth, int type, void *req, int len)