All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH libnetfilter_queue 0/2] Add mangle functions for IPv6, IPv6/TCP and IPv6/UDP
@ 2019-12-20  5:53 Duncan Roe
  2019-12-20  5:53 ` [PATCH libnetfilter_queue 1/2] src: more IPv6 checksum fixes Duncan Roe
  2019-12-20  5:53 ` [PATCH libnetfilter_queue 2/2] src: add mangle functions for IPv6, IPv6/TCP and IPv6/UDP Duncan Roe
  0 siblings, 2 replies; 7+ messages in thread
From: Duncan Roe @ 2019-12-20  5:53 UTC (permalink / raw)
  To: pablo; +Cc: netfilter-devel

As before, the nfq6 testbed program exercises the new functions. nfq6 is part of
https://github.com/duncan-roe/nfq

The TODO item in src/extra/checksum.c is because the pseudo-header used in
udp & tcp checksums uses destination address from forwarding header if there
is one. Not a big deal for now, I would say.

Duncan Roe (2):
  src: more IPv6 checksum fixes
  src: add mangle functions for IPv6, IPv6/TCP and IPv6/UDP

 .../libnetfilter_queue/libnetfilter_queue_ipv6.h   |  1 +
 .../libnetfilter_queue/libnetfilter_queue_tcp.h    |  1 +
 .../libnetfilter_queue/libnetfilter_queue_udp.h    |  1 +
 src/extra/checksum.c                               | 10 +++---
 src/extra/ipv6.c                                   | 29 ++++++++++++++++
 src/extra/tcp.c                                    | 40 ++++++++++++++++++++++
 src/extra/udp.c                                    | 39 +++++++++++++++++++++
 7 files changed, 116 insertions(+), 5 deletions(-)

--
2.14.5


^ permalink raw reply	[flat|nested] 7+ messages in thread

* [PATCH libnetfilter_queue 1/2] src: more IPv6 checksum fixes
  2019-12-20  5:53 [PATCH libnetfilter_queue 0/2] Add mangle functions for IPv6, IPv6/TCP and IPv6/UDP Duncan Roe
@ 2019-12-20  5:53 ` Duncan Roe
  2019-12-30 11:33   ` Pablo Neira Ayuso
  2019-12-20  5:53 ` [PATCH libnetfilter_queue 2/2] src: add mangle functions for IPv6, IPv6/TCP and IPv6/UDP Duncan Roe
  1 sibling, 1 reply; 7+ messages in thread
From: Duncan Roe @ 2019-12-20  5:53 UTC (permalink / raw)
  To: pablo; +Cc: netfilter-devel

Updated:

 src/extra/checksum.c: - Fix calculation of header length
                       - Upgrade calculation of payload length: Allow for extra
                         headers before the UDP header
                       - Delete "sum += ... s6_addr16[i] >> 16" lines,
                         since uint16_t >> 16 == 0
                       - Use upgraded payload length in pseudo-header

Signed-off-by: Duncan Roe <duncan_roe@optusnet.com.au>
---
 src/extra/checksum.c | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/src/extra/checksum.c b/src/extra/checksum.c
index 42389aa..8b23997 100644
--- a/src/extra/checksum.c
+++ b/src/extra/checksum.c
@@ -62,21 +62,21 @@ uint16_t nfq_checksum_tcpudp_ipv6(struct ip6_hdr *ip6h, void *transport_hdr,
 				  uint16_t protonum)
 {
 	uint32_t sum = 0;
-	uint32_t hdr_len = (uint32_t *)transport_hdr - (uint32_t *)ip6h;
-	uint32_t len = ip6h->ip6_plen - hdr_len;
+	uint32_t hdr_len = (uint8_t *)transport_hdr - (uint8_t *)ip6h;
+	/* Allow for extra headers before the UDP header */
+	/* TODO: Deal with routing headers */
+	uint32_t len = ntohs(ip6h->ip6_plen) - (hdr_len - sizeof *ip6h);
 	uint8_t *payload = (uint8_t *)ip6h + hdr_len;
 	int i;
 
 	for (i=0; i<8; i++) {
-		sum += (ip6h->ip6_src.s6_addr16[i] >> 16) & 0xFFFF;
 		sum += (ip6h->ip6_src.s6_addr16[i]) & 0xFFFF;
 	}
 	for (i=0; i<8; i++) {
-		sum += (ip6h->ip6_dst.s6_addr16[i] >> 16) & 0xFFFF;
 		sum += (ip6h->ip6_dst.s6_addr16[i]) & 0xFFFF;
 	}
 	sum += htons(protonum);
-	sum += htons(ip6h->ip6_plen);
+	sum += htons(len);
 
 	return nfq_checksum(sum, (uint16_t *)payload, len);
 }
-- 
2.14.5


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH libnetfilter_queue 2/2] src: add mangle functions for IPv6, IPv6/TCP and IPv6/UDP
  2019-12-20  5:53 [PATCH libnetfilter_queue 0/2] Add mangle functions for IPv6, IPv6/TCP and IPv6/UDP Duncan Roe
  2019-12-20  5:53 ` [PATCH libnetfilter_queue 1/2] src: more IPv6 checksum fixes Duncan Roe
@ 2019-12-20  5:53 ` Duncan Roe
  2019-12-30 11:33   ` Pablo Neira Ayuso
  1 sibling, 1 reply; 7+ messages in thread
From: Duncan Roe @ 2019-12-20  5:53 UTC (permalink / raw)
  To: pablo; +Cc: netfilter-devel

Signed-off-by: Duncan Roe <duncan_roe@optusnet.com.au>
---
 .../libnetfilter_queue/libnetfilter_queue_ipv6.h   |  1 +
 .../libnetfilter_queue/libnetfilter_queue_tcp.h    |  1 +
 .../libnetfilter_queue/libnetfilter_queue_udp.h    |  1 +
 src/extra/ipv6.c                                   | 29 ++++++++++++++++
 src/extra/tcp.c                                    | 40 ++++++++++++++++++++++
 src/extra/udp.c                                    | 39 +++++++++++++++++++++
 6 files changed, 111 insertions(+)

diff --git a/include/libnetfilter_queue/libnetfilter_queue_ipv6.h b/include/libnetfilter_queue/libnetfilter_queue_ipv6.h
index 93452ce..c0a7d37 100644
--- a/include/libnetfilter_queue/libnetfilter_queue_ipv6.h
+++ b/include/libnetfilter_queue/libnetfilter_queue_ipv6.h
@@ -6,6 +6,7 @@ struct ip6_hdr;
 
 struct ip6_hdr *nfq_ip6_get_hdr(struct pkt_buff *pktb);
 int nfq_ip6_set_transport_header(struct pkt_buff *pktb, struct ip6_hdr *iph, uint8_t target);
+int nfq_ip6_mangle(struct pkt_buff *pktb, unsigned int dataoff,unsigned int match_offset, unsigned int match_len,const char *rep_buffer, unsigned int rep_len);
 int nfq_ip6_snprintf(char *buf, size_t size, const struct ip6_hdr *ip6h);
 
 #endif
diff --git a/include/libnetfilter_queue/libnetfilter_queue_tcp.h b/include/libnetfilter_queue/libnetfilter_queue_tcp.h
index c66dfb6..997d997 100644
--- a/include/libnetfilter_queue/libnetfilter_queue_tcp.h
+++ b/include/libnetfilter_queue/libnetfilter_queue_tcp.h
@@ -14,6 +14,7 @@ void nfq_tcp_compute_checksum_ipv4(struct tcphdr *tcph, struct iphdr *iph);
 void nfq_tcp_compute_checksum_ipv6(struct tcphdr *tcph, struct ip6_hdr *ip6h);
 
 int nfq_tcp_mangle_ipv4(struct pkt_buff *pkt, unsigned int match_offset, unsigned int match_len, const char *rep_buffer, unsigned int rep_len);
+int nfq_tcp_mangle_ipv6(struct pkt_buff *pkt, unsigned int match_offset, unsigned int match_len, const char *rep_buffer, unsigned int rep_len);
 
 int nfq_tcp_snprintf(char *buf, size_t size, const struct tcphdr *tcp);
 
diff --git a/include/libnetfilter_queue/libnetfilter_queue_udp.h b/include/libnetfilter_queue/libnetfilter_queue_udp.h
index f4b6c49..f9fd609 100644
--- a/include/libnetfilter_queue/libnetfilter_queue_udp.h
+++ b/include/libnetfilter_queue/libnetfilter_queue_udp.h
@@ -11,6 +11,7 @@ void nfq_udp_compute_checksum_ipv4(struct udphdr *udph, struct iphdr *iph);
 void nfq_udp_compute_checksum_ipv6(struct udphdr *udph, struct ip6_hdr *ip6h);
 
 int nfq_udp_mangle_ipv4(struct pkt_buff *pkt, unsigned int match_offset, unsigned int match_len, const char *rep_buffer, unsigned int rep_len);
+int nfq_udp_mangle_ipv6(struct pkt_buff *pktb, unsigned int match_offset, unsigned int match_len, const char *rep_buffer, unsigned int rep_len);
 
 int nfq_udp_snprintf(char *buf, size_t size, const struct udphdr *udp);
 
diff --git a/src/extra/ipv6.c b/src/extra/ipv6.c
index f685b3b..6e8820c 100644
--- a/src/extra/ipv6.c
+++ b/src/extra/ipv6.c
@@ -116,6 +116,35 @@ int nfq_ip6_set_transport_header(struct pkt_buff *pktb, struct ip6_hdr *ip6h,
 	return cur ? 1 : 0;
 }
 
+/**
+ * nfq_ip6_mangle - mangle IPv6 packet buffer
+ * \param pktb: Pointer to user-space network packet buffer
+ * \param dataoff: Offset to layer 4 header
+ * \param match_offset: Offset to content that you want to mangle
+ * \param match_len: Length of the existing content you want to mangle
+ * \param rep_buffer: Pointer to data you want to use to replace current content
+ * \param rep_len: Length of data you want to use to replace current content
+ * \returns 1 for success and 0 for failure. See pktb_mangle() for failure case
+ * \note This function updates the IPv6 length (if necessary)
+ */
+EXPORT_SYMBOL
+int nfq_ip6_mangle(struct pkt_buff *pktb, unsigned int dataoff,
+		   unsigned int match_offset, unsigned int match_len,
+		   const char *rep_buffer, unsigned int rep_len)
+{
+	struct ip6_hdr *ip6h = (struct ip6_hdr *)pktb->network_header;
+
+	if (!pktb_mangle(pktb, dataoff, match_offset, match_len, rep_buffer,
+			 rep_len))
+		return 0;
+
+	/* Fix IPv6 hdr length information */
+	ip6h->ip6_plen =
+		htons(pktb->tail - pktb->network_header - sizeof *ip6h);
+
+	return 1;
+}
+
 /**
  * nfq_ip6_snprintf - print IPv6 header into one buffer in iptables LOG format
  * \param buf: Pointer to buffer that is used to print the object
diff --git a/src/extra/tcp.c b/src/extra/tcp.c
index 136d7ea..8119843 100644
--- a/src/extra/tcp.c
+++ b/src/extra/tcp.c
@@ -21,6 +21,7 @@
 #include <libnetfilter_queue/libnetfilter_queue.h>
 #include <libnetfilter_queue/libnetfilter_queue_tcp.h>
 #include <libnetfilter_queue/libnetfilter_queue_ipv4.h>
+#include <libnetfilter_queue/libnetfilter_queue_ipv6.h>
 #include <libnetfilter_queue/pktbuff.h>
 
 #include "internal.h"
@@ -206,6 +207,45 @@ int nfq_tcp_mangle_ipv4(struct pkt_buff *pkt,
 	return 1;
 }
 
+/**
+ * nfq_tcp_mangle_ipv6 - Mangle TCP/IPv6 packet buffer
+ * \param pktb: Pointer to network packet buffer
+ * \param match_offset: Offset from start of TCP data of content that you want
+ * to mangle
+ * \param match_len: Length of the existing content you want to mangle
+ * \param rep_buffer: Pointer to data you want to use to replace current content
+ * \param rep_len: Length of data you want to use to replace current content
+ * \returns 1 for success and 0 for failure. See pktb_mangle() for failure case
+ * \note This function updates the IPv6 length and recalculates the TCP
+ * checksum for you.
+ * \warning After changing the length of a TCP message, the application will
+ * need to mangle sequence numbers in both directions until another change
+ * puts them in sync again
+ */
+EXPORT_SYMBOL
+int nfq_tcp_mangle_ipv6(struct pkt_buff *pktb,
+			unsigned int match_offset, unsigned int match_len,
+			const char *rep_buffer, unsigned int rep_len)
+{
+	struct ip6_hdr *ip6h;
+	struct tcphdr *tcph;
+
+	ip6h = (struct ip6_hdr *)pktb->network_header;
+	tcph = (struct tcphdr *)(pktb->transport_header);
+	if (!tcph)
+		return 0;
+
+	if (!nfq_ip6_mangle(pktb,
+			   pktb->transport_header - pktb->network_header +
+			   tcph->doff * 4,
+			   match_offset, match_len, rep_buffer, rep_len))
+		return 0;
+
+	nfq_tcp_compute_checksum_ipv6(tcph, ip6h);
+
+	return 1;
+}
+
 /**
  * @}
  */
diff --git a/src/extra/udp.c b/src/extra/udp.c
index 34dbf2a..9eee1c7 100644
--- a/src/extra/udp.c
+++ b/src/extra/udp.c
@@ -20,6 +20,7 @@
 #include <libnetfilter_queue/libnetfilter_queue.h>
 #include <libnetfilter_queue/libnetfilter_queue_udp.h>
 #include <libnetfilter_queue/libnetfilter_queue_ipv4.h>
+#include <libnetfilter_queue/libnetfilter_queue_ipv6.h>
 #include <libnetfilter_queue/pktbuff.h>
 
 #include "internal.h"
@@ -159,6 +160,44 @@ int nfq_udp_mangle_ipv4(struct pkt_buff *pktb,
 	return 1;
 }
 
+/**
+ * nfq_udp_mangle_ipv6 - Mangle UDP/IPv6 packet buffer
+ * \param pktb: Pointer to network packet buffer
+ * \param match_offset: Offset from start of UDP data of content that you want
+ * to mangle
+ * \param match_len: Length of the existing content you want to mangle
+ * \param rep_buffer: Pointer to data you want to use to replace current content
+ * \param rep_len: Length of data you want to use to replace current content
+ * \returns 1 for success and 0 for failure. See pktb_mangle() for failure case
+ * \note This function updates the IPv6 and UDP lengths and recalculates the UDP
+ * checksum for you.
+ */
+EXPORT_SYMBOL
+int nfq_udp_mangle_ipv6(struct pkt_buff *pktb,
+			unsigned int match_offset, unsigned int match_len,
+			const char *rep_buffer, unsigned int rep_len)
+{
+	struct ip6_hdr *ip6h;
+	struct udphdr *udph;
+
+	ip6h = (struct ip6_hdr *)pktb->network_header;
+	udph = (struct udphdr *)(pktb->transport_header);
+	if (!udph)
+		return 0;
+
+	udph->len = htons(ntohs(udph->len) + rep_len - match_len);
+
+	if (!nfq_ip6_mangle(pktb,
+			    pktb->transport_header - pktb->network_header +
+			    sizeof(struct udphdr),
+			    match_offset, match_len, rep_buffer, rep_len))
+		return 0;
+
+	nfq_udp_compute_checksum_ipv6(udph, ip6h);
+
+	return 1;
+}
+
 /**
  * nfq_pkt_snprintf_udp_hdr - print udp header into one buffer in a humnan
  * readable way
-- 
2.14.5


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* Re: [PATCH libnetfilter_queue 1/2] src: more IPv6 checksum fixes
  2019-12-20  5:53 ` [PATCH libnetfilter_queue 1/2] src: more IPv6 checksum fixes Duncan Roe
@ 2019-12-30 11:33   ` Pablo Neira Ayuso
  2019-12-31  1:06     ` [PATCH libnetfilter_queue] src: checksum.c: remove redundant 0xFFFF mask of uint16_t Duncan Roe
  0 siblings, 1 reply; 7+ messages in thread
From: Pablo Neira Ayuso @ 2019-12-30 11:33 UTC (permalink / raw)
  To: Duncan Roe; +Cc: netfilter-devel

Applied, thanks for fixing up this. Comment below.

On Fri, Dec 20, 2019 at 04:53:47PM +1100, Duncan Roe wrote:
> diff --git a/src/extra/checksum.c b/src/extra/checksum.c
> index 42389aa..8b23997 100644
> --- a/src/extra/checksum.c
> +++ b/src/extra/checksum.c
> @@ -62,21 +62,21 @@ uint16_t nfq_checksum_tcpudp_ipv6(struct ip6_hdr *ip6h, void *transport_hdr,
>  				  uint16_t protonum)
>  {
>  	uint32_t sum = 0;
> -	uint32_t hdr_len = (uint32_t *)transport_hdr - (uint32_t *)ip6h;
> -	uint32_t len = ip6h->ip6_plen - hdr_len;
> +	uint32_t hdr_len = (uint8_t *)transport_hdr - (uint8_t *)ip6h;
> +	/* Allow for extra headers before the UDP header */
> +	/* TODO: Deal with routing headers */
> +	uint32_t len = ntohs(ip6h->ip6_plen) - (hdr_len - sizeof *ip6h);
>  	uint8_t *payload = (uint8_t *)ip6h + hdr_len;
>  	int i;
>  
>  	for (i=0; i<8; i++) {
> -		sum += (ip6h->ip6_src.s6_addr16[i] >> 16) & 0xFFFF;
>  		sum += (ip6h->ip6_src.s6_addr16[i]) & 0xFFFF;

I think you can also send a follow up to clean up this: Remove the 0xFFFF.

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH libnetfilter_queue 2/2] src: add mangle functions for IPv6, IPv6/TCP and IPv6/UDP
  2019-12-20  5:53 ` [PATCH libnetfilter_queue 2/2] src: add mangle functions for IPv6, IPv6/TCP and IPv6/UDP Duncan Roe
@ 2019-12-30 11:33   ` Pablo Neira Ayuso
  0 siblings, 0 replies; 7+ messages in thread
From: Pablo Neira Ayuso @ 2019-12-30 11:33 UTC (permalink / raw)
  To: Duncan Roe; +Cc: netfilter-devel

Also applied, thanks.

^ permalink raw reply	[flat|nested] 7+ messages in thread

* [PATCH libnetfilter_queue] src: checksum.c: remove redundant 0xFFFF mask of uint16_t
  2019-12-30 11:33   ` Pablo Neira Ayuso
@ 2019-12-31  1:06     ` Duncan Roe
  2020-01-03 12:25       ` Florian Westphal
  0 siblings, 1 reply; 7+ messages in thread
From: Duncan Roe @ 2019-12-31  1:06 UTC (permalink / raw)
  To: pablo; +Cc: netfilter-devel

Signed-off-by: Duncan Roe <duncan_roe@optusnet.com.au>
---
 src/extra/checksum.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/extra/checksum.c b/src/extra/checksum.c
index 8b23997..a650b64 100644
--- a/src/extra/checksum.c
+++ b/src/extra/checksum.c
@@ -70,10 +70,10 @@ uint16_t nfq_checksum_tcpudp_ipv6(struct ip6_hdr *ip6h, void *transport_hdr,
 	int i;
 
 	for (i=0; i<8; i++) {
-		sum += (ip6h->ip6_src.s6_addr16[i]) & 0xFFFF;
+		sum += (ip6h->ip6_src.s6_addr16[i]);
 	}
 	for (i=0; i<8; i++) {
-		sum += (ip6h->ip6_dst.s6_addr16[i]) & 0xFFFF;
+		sum += (ip6h->ip6_dst.s6_addr16[i]);
 	}
 	sum += htons(protonum);
 	sum += htons(len);
-- 
2.14.5


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* Re: [PATCH libnetfilter_queue] src: checksum.c: remove redundant 0xFFFF mask of uint16_t
  2019-12-31  1:06     ` [PATCH libnetfilter_queue] src: checksum.c: remove redundant 0xFFFF mask of uint16_t Duncan Roe
@ 2020-01-03 12:25       ` Florian Westphal
  0 siblings, 0 replies; 7+ messages in thread
From: Florian Westphal @ 2020-01-03 12:25 UTC (permalink / raw)
  To: Duncan Roe; +Cc: pablo, netfilter-devel

Duncan Roe <duncan_roe@optusnet.com.au> wrote:

Applied.

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2020-01-03 12:25 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-12-20  5:53 [PATCH libnetfilter_queue 0/2] Add mangle functions for IPv6, IPv6/TCP and IPv6/UDP Duncan Roe
2019-12-20  5:53 ` [PATCH libnetfilter_queue 1/2] src: more IPv6 checksum fixes Duncan Roe
2019-12-30 11:33   ` Pablo Neira Ayuso
2019-12-31  1:06     ` [PATCH libnetfilter_queue] src: checksum.c: remove redundant 0xFFFF mask of uint16_t Duncan Roe
2020-01-03 12:25       ` Florian Westphal
2019-12-20  5:53 ` [PATCH libnetfilter_queue 2/2] src: add mangle functions for IPv6, IPv6/TCP and IPv6/UDP Duncan Roe
2019-12-30 11:33   ` Pablo Neira Ayuso

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.