#include <unistd.h>
#include <errno.h>
#include <string.h>
+#include <sys/ioctl.h>
#include "netlink.h"
+#include "log.h"
struct AvahiNetlink {
GMainContext *context;
GSource *source;
void (*callback) (AvahiNetlink *nl, struct nlmsghdr *n, gpointer userdata);
gpointer userdata;
+ guint8* buffer;
+ guint buffer_length;
};
gboolean avahi_netlink_work(AvahiNetlink *nl, gboolean block) {
g_assert(nl);
for (;;) {
- guint8 replybuf[64*1024];
ssize_t bytes;
- struct nlmsghdr *p = (struct nlmsghdr *) replybuf;
+ struct nlmsghdr *p;
- if ((bytes = recv(nl->fd, replybuf, sizeof(replybuf), block ? 0 : MSG_DONTWAIT)) < 0) {
+ for (;;) {
+ if ((bytes = recv(nl->fd, nl->buffer, nl->buffer_length, block ? 0 : MSG_DONTWAIT)) < 0) {
- if (errno == EAGAIN || errno == EINTR)
- break;
+ if (errno == EAGAIN || errno == EINTR)
+ return TRUE;
+
+ avahi_log_warn("NETLINK: recv() failed: %s", strerror(errno));
+ return FALSE;
+ }
- g_warning("NETLINK: recv() failed");
- return FALSE;
+ break;
}
+ p = (struct nlmsghdr *) nl->buffer;
+
if (nl->callback) {
for (; bytes > 0; p = NLMSG_NEXT(p, bytes)) {
if (!NLMSG_OK(p, (size_t) bytes)) {
- g_warning("NETLINK: packet truncated");
+ avahi_log_warn("NETLINK: packet truncated");
return FALSE;
}
}
if (block)
- break;
+ return TRUE;
}
-
- return TRUE;
}
static gboolean prepare_func(GSource *source, gint *timeout) {
NULL
};
- g_assert(context);
g_assert(cb);
if ((fd = socket(PF_NETLINK, SOCK_DGRAM, NETLINK_ROUTE)) < 0) {
}
nl = g_new(AvahiNetlink, 1);
- nl->context = context;
- g_main_context_ref(context);
+ g_main_context_ref(nl->context = context ? context : g_main_context_default());
nl->fd = fd;
nl->seq = 0;
nl->callback = cb;
nl->userdata = userdata;
+ nl->buffer = g_new(guint8, nl->buffer_length = 64*1024);
nl->source = g_source_new(&source_funcs, sizeof(GSource) + sizeof(AvahiNetlink*));
*((AvahiNetlink**) (((guint8*) nl->source) + sizeof(GSource))) = nl;
void avahi_netlink_free(AvahiNetlink *nl) {
g_assert(nl);
-
+
g_source_destroy(nl->source);
g_source_unref(nl->source);
g_main_context_unref(nl->context);
close(nl->fd);
+ g_free(nl->buffer);
g_free(nl);
}
m->nlmsg_flags |= NLM_F_ACK;
if (send(nl->fd, m, m->nlmsg_len, 0) < 0) {
- g_warning("NETLINK: send(): %s\n", strerror(errno));
+ avahi_log_warn("NETLINK: send(): %s\n", strerror(errno));
return -1;
}