diff --git a/daemon/nftables.c b/daemon/nftables.c index 5a739c40e..ef999128d 100644 --- a/daemon/nftables.c +++ b/daemon/nftables.c @@ -175,13 +175,13 @@ static char *iterate_rules(nfapi_socket *nl, int family, const char *chain, if (!nfapi_send_buf(nl, b)) return g_strdup_printf("failed to write to netlink socket trying to read rules (%s) " "(attempted: \"%s\")", - strerror(errno), nfapi_buf_msg(b)); + strerror(errno), nfapi_err_msg(nl)); const char *err = nfapi_recv_iter(nl, &(nfapi_callbacks) { .rule = nftables_do_rule }, callbacks); if (err) return g_strdup_printf("error received from netlink socket reading rules (%s): %s " "(attempted: \"%s\")", - strerror(errno), err, nfapi_buf_msg(b)); + strerror(errno), err, nfapi_err_msg(nl)); if (callbacks->iterate_final) { char *e = callbacks->iterate_final(nl, family, chain, callbacks); @@ -219,13 +219,13 @@ static char *delete_rules(nfapi_socket *nl, int family, const char *chain, if (!nfapi_send_buf(nl, b)) return g_strdup_printf("failed to write to netlink socket trying to delete rule (%s) " "(attempted: \"%s\")", - strerror(errno), nfapi_buf_msg(b)); + strerror(errno), nfapi_err_msg(nl)); const char *err = nfapi_recv_iter(nl, NULL, NULL); if (err) return g_strdup_printf("error received from netlink socket trying to delete rule (%s): %s " "(attempted: \"%s\")", - strerror(errno), err, nfapi_buf_msg(b)); + strerror(errno), err, nfapi_err_msg(nl)); return NULL; } @@ -307,7 +307,7 @@ static char *add_chain(nfapi_socket *nl, int family, const char *chain, if (err) return g_strdup_printf("error returned from callback trying to add chain: %s " "(attempted: \"%s\")", - err, nfapi_buf_msg(b)); + err, nfapi_err_msg(nl)); } nfapi_batch_end(b); @@ -315,13 +315,13 @@ static char *add_chain(nfapi_socket *nl, int family, const char *chain, if (!nfapi_send_buf(nl, b)) return g_strdup_printf("failed to write to netlink socket trying to add chain (%s) " "(attempted: \"%s\")", - strerror(errno), nfapi_buf_msg(b)); + strerror(errno), nfapi_err_msg(nl)); const char *err = nfapi_recv_iter(nl, NULL, NULL); if (err) return g_strdup_printf("error received from netlink socket trying to add chain (%s): %s " "(attempted: \"%s\")", - strerror(errno), err, nfapi_buf_msg(b)); + strerror(errno), err, nfapi_err_msg(nl)); return NULL; } @@ -343,20 +343,20 @@ static char *add_rule(nfapi_socket *nl, int family, if (err) return g_strdup_printf("error returned from callback trying to add table: %s " "(attempted: \"%s\")", - err, nfapi_buf_msg(b)); + err, nfapi_err_msg(nl)); nfapi_batch_end(b); if (!nfapi_send_buf(nl, b)) return g_strdup_printf("failed to write to netlink socket trying to add rule (%s) " "(attempted: \"%s\")", - strerror(errno), nfapi_buf_msg(b)); + strerror(errno), nfapi_err_msg(nl)); err = nfapi_recv_iter(nl, NULL, NULL); if (err) return g_strdup_printf("error received from netlink socket trying to add rule (%s): %s " "(attempted: \"%s\")", - strerror(errno), err, nfapi_buf_msg(b)); + strerror(errno), err, nfapi_err_msg(nl)); return NULL; } @@ -625,13 +625,13 @@ static char *delete_chain(nfapi_socket *nl, int family, const char *chain) { if (!nfapi_send_buf(nl, b)) return g_strdup_printf("failed to write to netlink socket trying to delete chain (%s) " "(attempted: \"%s\")", - strerror(errno), nfapi_buf_msg(b)); + strerror(errno), nfapi_err_msg(nl)); const char *err = nfapi_recv_iter(nl, NULL, NULL); if (err) return g_strdup_printf("error received from netlink socket trying to delete chain (%s): %s " "(attempted: \"%s\")", - strerror(errno), err, nfapi_buf_msg(b)); + strerror(errno), err, nfapi_err_msg(nl)); return NULL; } @@ -715,13 +715,13 @@ static char *add_table(nfapi_socket *nl, int family) { if (!nfapi_send_buf(nl, b)) return g_strdup_printf("failed to write to netlink socket trying to add table (%s) " "(attempted: \"%s\")", - strerror(errno), nfapi_buf_msg(b)); + strerror(errno), nfapi_err_msg(nl)); const char *err = nfapi_recv_iter(nl, NULL, NULL); if (err) return g_strdup_printf("error received from netlink socket trying to add table (%s): %s " "(attempted: \"%s\")", - strerror(errno), err, nfapi_buf_msg(b)); + strerror(errno), err, nfapi_err_msg(nl)); return NULL; } diff --git a/lib/netfilter_api.c b/lib/netfilter_api.c index 0f9f093de..15de8f260 100644 --- a/lib/netfilter_api.c +++ b/lib/netfilter_api.c @@ -19,6 +19,8 @@ struct nfapi_socket { int fd; struct sockaddr_nl addr; // local uint16_t seq; + GHashTable *msgs; + uint16_t err_seq; }; struct nfapi_buf { @@ -55,6 +57,7 @@ nfapi_socket *nfapi_socket_open(void) { nfapi_socket *s = g_new0(__typeof(*s), 1); s->fd = fd; s->addr = saddr; + s->msgs = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, g_free); return s; } @@ -62,9 +65,15 @@ nfapi_socket *nfapi_socket_open(void) { void nfapi_socket_close(nfapi_socket *s) { if (s->fd != -1) close(s->fd); + g_hash_table_destroy(s->msgs); g_free(s); } +const char *nfapi_err_msg(nfapi_socket *s) { + const char *m = g_hash_table_lookup(s->msgs, GUINT_TO_POINTER(s->err_seq)); + return m ?: "?"; +} + nfapi_buf *nfapi_buf_new(nfapi_socket *s) { nfapi_buf *b = g_new0(__typeof(*b), 1); @@ -81,10 +90,6 @@ void nfapi_buf_free(nfapi_buf *b) { g_free(b); } -const char *nfapi_buf_msg(nfapi_buf *b) { - return b->readable->str; -} - static void readable_vadd(GString *r, const char *fmt, va_list va) { if (r->len > 0) @@ -193,6 +198,10 @@ void nfapi_nested_end(nfapi_buf *b) { bool nfapi_send_buf(nfapi_socket *s, nfapi_buf *b) { + char *msg = g_string_free(b->readable, FALSE); + g_hash_table_replace(s->msgs, GUINT_TO_POINTER(b->seq), msg); + b->readable = g_string_new(""); + ssize_t ret = sendto(s->fd, b->s->str, b->s->len, 0, (struct sockaddr *) &zero_nl_sockaddr, sizeof(zero_nl_sockaddr)); if (ret != b->s->len) @@ -285,6 +294,7 @@ const char *nfapi_recv_iter(nfapi_socket *s, const nfapi_callbacks *c, void *use return NULL; errno = -err->error; + s->err_seq = hdr->nlmsg_seq; return "error returned from netlink, see errno"; } else diff --git a/lib/netfilter_api.h b/lib/netfilter_api.h index 6aa946a1d..94b407abe 100644 --- a/lib/netfilter_api.h +++ b/lib/netfilter_api.h @@ -20,11 +20,11 @@ typedef struct { nfapi_socket *nfapi_socket_open(void); void nfapi_socket_close(nfapi_socket *); +const char *nfapi_err_msg(nfapi_socket *); nfapi_buf *nfapi_buf_new(nfapi_socket *); void nfapi_buf_free(nfapi_buf *); -const char *nfapi_buf_msg(nfapi_buf *); __attribute__ ((format(printf, 5, 6))) void nfapi_add_msg(nfapi_buf *, uint16_t type, uint16_t family, uint16_t flags, const char *fmt, ...);