From 7e670e95001a6e88e031435cda58933710720ebd Mon Sep 17 00:00:00 2001 From: kaber Date: Thu, 4 Mar 2004 20:00:57 +0000 Subject: Complete nfnl_talk, fix "concatenation with __FUNCTION__ ..." warnings (Patrick McHardy) --- libnfnetlink.c | 63 +++++++++++++++++++++++++++++++++++++++++++++++++++------- libnfnetlink.h | 44 +++++++++++++++++----------------------- 2 files changed, 74 insertions(+), 33 deletions(-) diff --git a/libnfnetlink.c b/libnfnetlink.c index fb883be..4bb3362 100644 --- a/libnfnetlink.c +++ b/libnfnetlink.c @@ -21,7 +21,7 @@ #include "libnfnetlink.h" #define nfnl_error(format, args...) \ - fprintf(stderr, __FUNCTION__ ": " format "\n", ## args) + fprintf(stderr, "%s: " format "\n", __FUNCTION__, ## args) #ifdef _NFNL_DEBUG #define nfnl_debug_dump_packet nfnl_dump_packet @@ -35,7 +35,7 @@ void nfnl_dump_packet(struct nlmsghdr *nlh, int received_len, char *desc) struct nfattr *nfa = NFM_NFA(NLMSG_DATA(nlh)); int len = NFM_PAYLOAD(nlh); - printf(__FUNCTION__ " called from %s\n", desc); + printf("%s called from %s\n", __FUNCTION__, desc); printf(" nlmsghdr = %p, received_len = %u\n", nlh, received_len); printf(" NLMSG_DATA(nlh) = %p (+%u bytes)\n", nlmsg_data, (nlmsg_data - (void *)nlh)); @@ -250,13 +250,12 @@ int nfnl_listen(struct nfnl_handle *nfnlh, return 0; } -#if 0 int nfnl_talk(struct nfnl_handle *nfnlh, struct nlmsghdr *n, pid_t peer, unsigned groups, struct nlmsghdr *answer, int (*junk)(struct sockaddr_nl *, struct nlmsghdr *n, void *), void *jarg) { - char buf[CTNL_BUFFSIZE]; + char buf[NFNL_BUFFSIZE]; struct sockaddr_nl nladdr; struct nlmsghdr *h; unsigned int seq; @@ -307,15 +306,65 @@ int nfnl_talk(struct nfnl_handle *nfnlh, struct nlmsghdr *n, pid_t peer, return -1; } - for (h = (struct nlmsghdr *)buf; status >= sizeof(*h)) { + for (h = (struct nlmsghdr *)buf; status >= sizeof(*h); ) { int len = h->nlmsg_len; int l = len - sizeof(*h); int err; - + if (l < 0 || len > status) { + if (msg.msg_flags & MSG_TRUNC) { + nfnl_error("Truncated message\n"); + return -1; + } + nfnl_error("Malformed message: len=%d\n", len); + return -1; /* FIXME: libnetlink exits here */ + } + + if (h->nlmsg_pid != nfnlh->local.nl_pid || + h->nlmsg_seq != seq) { + if (junk) { + err = junk(&nladdr, h, jarg); + if (err < 0) + return err; + } + continue; + } + if (h->nlmsg_type == NLMSG_ERROR) { + struct nlmsgerr *err = NLMSG_DATA(h); + if (l < sizeof(struct nlmsgerr)) + nfnl_error("ERROR truncated\n"); + else { + errno = -err->error; + if (errno == 0) { + if (answer) + memcpy(answer, h, h->nlmsg_len); + return 0; + } + perror("CTNETLINK answers"); + } + return -1; + } + if (answer) { + memcpy(answer, h, h->nlmsg_len); + return 0; + } + + nfnl_error("Unexpected reply!\n"); + + status -= NLMSG_ALIGN(len); + h = (struct nlmsghdr *)((char *)h + NLMSG_ALIGN(len)); + } + if (msg.msg_flags & MSG_TRUNC) { + nfnl_error("Messages truncated\n"); + continue; + } + if (status) { + nfnl_error("Remnant of size %d\n", status); + exit(1); + } + } } -#endif /** * nfnl_addattr_l - Add variable length attribute to nlmsghdr diff --git a/libnfnetlink.h b/libnfnetlink.h index eab14e9..61558ed 100644 --- a/libnfnetlink.h +++ b/libnfnetlink.h @@ -22,37 +22,29 @@ struct nfnl_handle { }; /* get a new library handle */ -extern int nfnl_open(struct nfnl_handle *nfnlh, u_int8_t subsys_id, - unsigned int subscriptions); -extern int nfnl_close(struct nfnl_handle *nfnlh); +extern int nfnl_open(struct nfnl_handle *, u_int8_t, unsigned int); +extern int nfnl_close(struct nfnl_handle *); +extern int nfnl_send(struct nfnl_handle *, struct nlmsghdr *); -int nfnl_send(struct nfnl_handle *nfnlh, struct nlmsghdr *n); - - -void nfnl_fill_hdr(struct nfnl_handle *nfnlh, - struct nlmsghdr *nlh, int len, - u_int8_t family, - u_int16_t msg_type, - u_int16_t msg_flags); - -int nfnl_listen(struct nfnl_handle *nfnlh, - int (*handler)(struct sockaddr_nl *, struct nlmsghdr *n, - void *), void *jarg); +extern void nfnl_fill_hdr(struct nfnl_handle *, struct nlmsghdr *, int, + u_int8_t, u_int16_t, u_int16_t); +extern int nfnl_listen(struct nfnl_handle *, + int (*)(struct sockaddr_nl *, struct nlmsghdr *, void *), + void *); +extern int nfnl_talk(struct nfnl_handle *, struct nlmsghdr *, pid_t, + unsigned, struct nlmsghdr *, + int (*)(struct sockaddr_nl *, struct nlmsghdr *, void *), + void *); /* nfnl attribute handling functions */ -int nfnl_addattr_l(struct nlmsghdr *n, int maxlen, int type, void *data, - int alen); -int nfnl_addattr32(struct nlmsghdr *n, int maxlen, int type, - u_int32_t data); -int nfnl_nfa_addattr_l(struct nfattr *nfa, int maxlen, int type, void *data, - int alen); -int nfnl_nfa_addattr32(struct nfattr *nfa, int maxlen, int type, - u_int32_t data); -int nfnl_parse_attr(struct nfattr *tb[], int max, struct nfattr *nfa, int len); - -void nfnl_dump_packet(struct nlmsghdr *nlh, int received_len, char *desc); +extern int nfnl_addattr_l(struct nlmsghdr *, int, int, void *, int); +extern int nfnl_addattr32(struct nlmsghdr *, int, int, u_int32_t); +extern int nfnl_nfa_addattr_l(struct nfattr *, int, int, void *, int); +extern int nfnl_nfa_addattr32(struct nfattr *, int, int, u_int32_t); +extern int nfnl_parse_attr(struct nfattr **, int, struct nfattr *, int); +extern void nfnl_dump_packet(struct nlmsghdr *, int, char *); #endif /* __LIBNFNETLINK_H */ -- cgit v1.2.3