Index: libctnetlink/libctnetlink.c
===================================================================
RCS file: /cvspublic/netfilter/iptables2/libctnetlink/libctnetlink.c,v
retrieving revision 1.3
diff -u -r1.3 libctnetlink.c
--- libctnetlink/libctnetlink.c	8 Aug 2002 10:27:46 -0000	1.3
+++ libctnetlink/libctnetlink.c	9 Jun 2003 21:10:28 -0000
@@ -34,7 +34,7 @@
 #include "libctnetlink.h"
 
 #define ctnl_error(format, args...) \
-	fprintf(stderr, __FUNCTION__ ": " format, ## args)
+	fprintf(stderr, "%s: " format, __FUNCTION__, ## args)
 
 /***********************************************************************
  * low level stuff 
Index: libnfnetlink/libnfnetlink.c
===================================================================
RCS file: /cvspublic/netfilter/iptables2/libnfnetlink/libnfnetlink.c,v
retrieving revision 1.2
diff -u -r1.2 libnfnetlink.c
--- libnfnetlink/libnfnetlink.c	2 Aug 2002 08:17:18 -0000	1.2
+++ libnfnetlink/libnfnetlink.c	9 Jun 2003 21:10:29 -0000
@@ -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 @@
 	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 @@
 	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 @@
 			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
Index: libnfnetlink/libnfnetlink.h
===================================================================
RCS file: /cvspublic/netfilter/iptables2/libnfnetlink/libnfnetlink.h,v
retrieving revision 1.2
diff -u -r1.2 libnfnetlink.h
--- libnfnetlink/libnfnetlink.h	2 Aug 2002 08:17:18 -0000	1.2
+++ libnfnetlink/libnfnetlink.h	9 Jun 2003 21:10:29 -0000
@@ -22,37 +22,29 @@
 };
 
 /* 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);
-
-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 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 *);
+
+
+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 */
