changeset 1414:f6f12521c2aa

Fix strict-aliasing warnings with gcc 4.8 Rewrite IN6_ADDR_V4MAP() to not rely upon aliasing rules. Add test for IN6_ADDR_V4MAP() and IN6_ADDR_V4UNMAP(). Rewrite MD5Final() to not rely upon aliasing rules. (Not tested)
author Luke Mewburn <luke@mewburn.net>
date Tue, 18 Feb 2020 19:01:49 +1100
parents 1979715b744f
children 3d7108b831e1
files extensions/app_radgw/md5.c extensions/app_sip/md5.c include/freeDiameter/libfdproto.h tests/testmesg.c
diffstat 4 files changed, 29 insertions(+), 8 deletions(-) [+]
line wrap: on
line diff
--- a/extensions/app_radgw/md5.c	Tue Feb 18 18:38:00 2020 +1100
+++ b/extensions/app_radgw/md5.c	Tue Feb 18 19:01:49 2020 +1100
@@ -286,8 +286,7 @@
     byteReverse(ctx->in, 14);
 
     /* Append length in bits and transform */
-    ((u32 *) ctx->in)[14] = ctx->bits[0];
-    ((u32 *) ctx->in)[15] = ctx->bits[1];
+    os_memcpy(&ctx->in[56], &ctx->bits[0], 8);
 
     MD5Transform(ctx->buf, (u32 *) ctx->in);
     byteReverse((unsigned char *) ctx->buf, 4);
--- a/extensions/app_sip/md5.c	Tue Feb 18 18:38:00 2020 +1100
+++ b/extensions/app_sip/md5.c	Tue Feb 18 19:01:49 2020 +1100
@@ -309,8 +309,7 @@
     byteReverse(ctx->in, 14);
 
     /* Append length in bits and transform */
-    ((u32 *) ctx->in)[14] = ctx->bits[0];
-    ((u32 *) ctx->in)[15] = ctx->bits[1];
+    os_memcpy(&ctx->in[56], &ctx->bits[0], 8);
 
     MD5Transform(ctx->buf, (u32 *) ctx->in);
     byteReverse((unsigned char *) ctx->buf, 4);
--- a/include/freeDiameter/libfdproto.h	Tue Feb 18 18:38:00 2020 +1100
+++ b/include/freeDiameter/libfdproto.h	Tue Feb 18 19:01:49 2020 +1100
@@ -689,10 +689,10 @@
 
 /* create a V4MAPPED address */
 #define IN6_ADDR_V4MAP( a6, a4 ) {			\
-	((uint32_t *)(a6))[0] = 0;			\
-	((uint32_t *)(a6))[1] = 0;			\
-	((uint32_t *)(a6))[2] = htonl(0xffff);		\
-	((uint32_t *)(a6))[3] = (uint32_t)(a4);		\
+	memset(&(*a6)[0], 0, 10);			\
+	(*a6)[10] = 0xff;				\
+	(*a6)[11] = 0xff;				\
+	memcpy(&(*a6)[12], &a4, 4);			\
 }
 
 /* Retrieve a v4 value from V4MAPPED address ( takes a s6_addr as param) */
--- a/tests/testmesg.c	Tue Feb 18 18:38:00 2020 +1100
+++ b/tests/testmesg.c	Tue Feb 18 19:01:49 2020 +1100
@@ -1448,6 +1448,29 @@
 			CHECK( 0, fd_msg_free( msg ) );
 		}
 	}
+
+	/* Check IPv4 -> IPv6 and IPv6->IPv4 mapping */
+	{
+		struct in_addr i4;
+		memset(&i4, 0xff, sizeof(i4));
+		CHECK( 1, inet_pton( AF_INET, TEST_IP4, &i4 ) );
+
+		#define TEST_IP6MAP "::ffff:" TEST_IP4
+
+		struct in6_addr i6;
+		memset(&i6, 0xff, sizeof(i6));
+		IN6_ADDR_V4MAP(&i6.s6_addr, i4.s_addr);
+		char buf6[INET6_ADDRSTRLEN];
+		CHECK( 0, (inet_ntop( AF_INET6, &i6, buf6, sizeof(buf6) ) == NULL) ? errno : 0 );
+		LOG_D("buf6='%s'", buf6);
+		CHECK( 0, strcasecmp( buf6, TEST_IP6MAP ) );
+
+		struct in_addr o4;
+		o4.s_addr = IN6_ADDR_V4UNMAP(&i6);
+		char buf4[INET_ADDRSTRLEN];
+		CHECK( 0, (inet_ntop( AF_INET, &o4.s_addr, buf4, sizeof(buf4) ) == NULL) ? errno : 0 );
+		CHECK( 0, strcmp( buf4, TEST_IP4 ) );
+	}
 	
 	/* That's all for the tests yet */
 	PASSTEST();
"Welcome to our mercurial repository"