From f966e5e186f14110a29d38d03992488d88348108 Mon Sep 17 00:00:00 2001
From: Mark Spencer <markster@digium.com>
Date: Tue, 29 Mar 2005 04:49:24 +0000
Subject: [PATCH] Simplify endianness and fix for unaligned reads (bug #3867)

git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@5295 65c4cc65-6c06-0410-ace0-fbb531ad65f3
---
 aesopt.h                     | 22 +--------
 channels/chan_alsa.c         |  2 +-
 channels/chan_oss.c          | 18 +------
 channels/iax2-parser.c       | 71 +++++++++++----------------
 dns.c                        |  5 +-
 formats/format_g726.c        | 10 +---
 formats/format_g729.c        | 10 +---
 formats/format_gsm.c         | 10 +---
 formats/format_h263.c        | 10 +---
 formats/format_ilbc.c        | 10 +---
 formats/format_jpeg.c        | 10 +---
 formats/format_pcm.c         | 10 +---
 formats/format_pcm_alaw.c    | 10 +---
 formats/format_sln.c         | 10 +---
 formats/format_vox.c         | 10 +---
 formats/format_wav.c         | 10 +---
 formats/format_wav_gsm.c     | 10 +---
 include/asterisk/endian.h    | 50 +++++++++++++++++++
 include/asterisk/frame.h     | 40 +--------------
 include/asterisk/unaligned.h | 95 ++++++++++++++++++++++++++++++++++++
 md5.c                        | 21 ++------
 rtp.c                        | 19 ++------
 22 files changed, 200 insertions(+), 263 deletions(-)
 create mode 100755 include/asterisk/endian.h
 create mode 100755 include/asterisk/unaligned.h

diff --git a/aesopt.h b/aesopt.h
index f476de09e8..85ad46688b 100755
--- a/aesopt.h
+++ b/aesopt.h
@@ -136,6 +136,7 @@
 #define _AESOPT_H
 
 #include <asterisk/aes.h>
+#include <asterisk/endian.h>
 
 /*  CONFIGURATION - USE OF DEFINES
 
@@ -146,27 +147,6 @@
     #if clauses.
 */
 
-/*  PLATFORM SPECIFIC INCLUDES */
-
-#if defined( __OpenBSD__ )
-#  include <machine/types.h>
-#  include <sys/endian.h>
-#elif defined( __FreeBSD__ ) || defined( __NetBSD__ )
-#  include <sys/types.h>
-#  include <sys/endian.h>
-#elif defined( BSD ) && ( BSD >= 199103 ) || defined(__APPLE__)
-#  include <machine/endian.h>
-#elif defined ( SOLARIS )
-#  include <solaris-compat/compat.h>
-#elif defined( __GNUC__ ) || defined( __GNU_LIBRARY__ )
-#  include <endian.h>
-#if !defined(__APPLE__)
-#  include <byteswap.h>
-#endif
-#elif defined( linux )
-#  include <endian.h>
-#endif
-
 /*  BYTE ORDER IN 32-BIT WORDS
 
     To obtain the highest speed on processors with 32-bit words, this code
diff --git a/channels/chan_alsa.c b/channels/chan_alsa.c
index 9811cb8d2c..fb2b93b30e 100755
--- a/channels/chan_alsa.c
+++ b/channels/chan_alsa.c
@@ -19,6 +19,7 @@
 #include <asterisk/cli.h>
 #include <asterisk/utils.h>
 #include <asterisk/causes.h>
+#include <asterisk/endian.h>
 #include <unistd.h>
 #include <fcntl.h>
 #include <errno.h>
@@ -27,7 +28,6 @@
 #include <string.h>
 #include <stdlib.h>
 #include <stdio.h>
-#include <endian.h>
 
 #define ALSA_PCM_NEW_HW_PARAMS_API
 #define ALSA_PCM_NEW_SW_PARAMS_API
diff --git a/channels/chan_oss.c b/channels/chan_oss.c
index 480408eb75..6a580d48c4 100755
--- a/channels/chan_oss.c
+++ b/channels/chan_oss.c
@@ -26,6 +26,7 @@
 #include <asterisk/cli.h>
 #include <asterisk/utils.h>
 #include <asterisk/causes.h>
+#include <asterisk/endian.h>
 #include <unistd.h>
 #include <fcntl.h>
 #include <errno.h>
@@ -35,23 +36,6 @@
 #include <stdlib.h>
 #include <stdio.h>
 
-#if defined( __OpenBSD__ )
-#  include <sys/endian.h>
-#elif defined( __FreeBSD__ ) || defined( __NetBSD__ )
-#  include <sys/endian.h>   
-#elif defined( BSD ) && ( BSD >= 199103 ) || defined(__APPLE__)
-#  include <machine/endian.h>
-#elif defined ( SOLARIS )
-#  include <solaris-compat/compat.h>
-#elif defined( __GNUC__ ) || defined( __GNU_LIBRARY__ )
-#  include <endian.h>
-#if !defined(__APPLE__)
-#  include <byteswap.h>
-#endif
-#elif defined( linux )
-#  include <endian.h>
-#endif
-
 #ifdef __linux
 #include <linux/soundcard.h>
 #elif defined(__FreeBSD__)
diff --git a/channels/iax2-parser.c b/channels/iax2-parser.c
index 66a69b447e..3472b5008d 100755
--- a/channels/iax2-parser.c
+++ b/channels/iax2-parser.c
@@ -17,6 +17,7 @@
 #include <netinet/in.h>
 #include <asterisk/frame.h>
 #include <asterisk/utils.h>
+#include <asterisk/unaligned.h>
 #include <arpa/inet.h>
 #include <unistd.h>
 #include <stdlib.h>
@@ -30,22 +31,6 @@ static int frames = 0;
 static int iframes = 0;
 static int oframes = 0;
 
-#if defined(SOLARIS) && defined(__sparc__)
-static unsigned int get_uint32(unsigned char *p)
-{
-  return (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3];
-}
-
-static unsigned short get_uint16(unsigned char *p)
-{
-  return (p[0] << 8) | p[1] ;
-}
-
-#else
-#define get_uint32(p) (*((unsigned int *)(p)))
-#define get_uint16(p) (*((unsigned short *)(p)))
-#endif
-
 static void internaloutput(const char *str)
 {
 	fputs(str, stdout);
@@ -102,7 +87,7 @@ static void dump_prefs(char *output, int maxlen, void *value, int len)
 static void dump_int(char *output, int maxlen, void *value, int len)
 {
 	if (len == (int)sizeof(unsigned int))
-		snprintf(output, maxlen, "%lu", (unsigned long)ntohl(get_uint32(value)));
+		snprintf(output, maxlen, "%lu", (unsigned long)ntohl(get_unaligned_uint32(value)));
 	else
 		snprintf(output, maxlen, "Invalid INT");
 }
@@ -110,7 +95,7 @@ static void dump_int(char *output, int maxlen, void *value, int len)
 static void dump_short(char *output, int maxlen, void *value, int len)
 {
 	if (len == (int)sizeof(unsigned short))
-		snprintf(output, maxlen, "%d", ntohs(get_uint16(value)));
+		snprintf(output, maxlen, "%d", ntohs(get_unaligned_uint16(value)));
 	else
 		snprintf(output, maxlen, "Invalid SHORT");
 }
@@ -140,8 +125,8 @@ static void dump_prov_flags(char *output, int maxlen, void *value, int len)
 {
 	char buf[256] = "";
 	if (len == (int)sizeof(unsigned int))
-		snprintf(output, maxlen, "%lu (%s)", (unsigned long)ntohl(get_uint32(value)),
-			iax_provflags2str(buf, sizeof(buf), ntohl(get_uint32(value))));
+		snprintf(output, maxlen, "%lu (%s)", (unsigned long)ntohl(get_unaligned_uint32(value)),
+			iax_provflags2str(buf, sizeof(buf), ntohl(get_unaligned_uint32(value))));
 	else
 		snprintf(output, maxlen, "Invalid INT");
 }
@@ -600,14 +585,14 @@ int iax_parse_ies(struct iax_ies *ies, unsigned char *data, int datalen)
 				snprintf(tmp, (int)sizeof(tmp), "Expecting capability to be %d bytes long but was %d\n", (int)sizeof(unsigned int), len);
 				errorf(tmp);
 			} else
-				ies->capability = ntohl(get_uint32(data + 2));
+				ies->capability = ntohl(get_unaligned_uint32(data + 2));
 			break;
 		case IAX_IE_FORMAT:
 			if (len != (int)sizeof(unsigned int)) {
 				snprintf(tmp, (int)sizeof(tmp), "Expecting format to be %d bytes long but was %d\n", (int)sizeof(unsigned int), len);
 				errorf(tmp);
 			} else
-				ies->format = ntohl(get_uint32(data + 2));
+				ies->format = ntohl(get_unaligned_uint32(data + 2));
 			break;
 		case IAX_IE_LANGUAGE:
 			ies->language = data + 2;
@@ -617,21 +602,21 @@ int iax_parse_ies(struct iax_ies *ies, unsigned char *data, int datalen)
 				snprintf(tmp, (int)sizeof(tmp),  "Expecting version to be %d bytes long but was %d\n", (int)sizeof(unsigned short), len);
 				errorf(tmp);
 			} else
-				ies->version = ntohs(get_uint16(data + 2));
+				ies->version = ntohs(get_unaligned_uint16(data + 2));
 			break;
 		case IAX_IE_ADSICPE:
 			if (len != (int)sizeof(unsigned short)) {
 				snprintf(tmp, (int)sizeof(tmp), "Expecting adsicpe to be %d bytes long but was %d\n", (int)sizeof(unsigned short), len);
 				errorf(tmp);
 			} else
-				ies->adsicpe = ntohs(get_uint16(data + 2));
+				ies->adsicpe = ntohs(get_unaligned_uint16(data + 2));
 			break;
 		case IAX_IE_SAMPLINGRATE:
 			if (len != (int)sizeof(unsigned short)) {
 				snprintf(tmp, (int)sizeof(tmp), "Expecting samplingrate to be %d bytes long but was %d\n", (int)sizeof(unsigned short), len);
 				errorf(tmp);
 			} else
-				ies->samprate = ntohs(get_uint16(data + 2));
+				ies->samprate = ntohs(get_unaligned_uint16(data + 2));
 			break;
 		case IAX_IE_DNID:
 			ies->dnid = data + 2;
@@ -644,14 +629,14 @@ int iax_parse_ies(struct iax_ies *ies, unsigned char *data, int datalen)
 				snprintf(tmp, (int)sizeof(tmp), "Expecting authmethods to be %d bytes long but was %d\n", (int)sizeof(unsigned short), len);
 				errorf(tmp);
 			} else
-				ies->authmethods = ntohs(get_uint16(data + 2));
+				ies->authmethods = ntohs(get_unaligned_uint16(data + 2));
 			break;
 		case IAX_IE_ENCRYPTION:
 			if (len != (int)sizeof(unsigned short))  {
 				snprintf(tmp, (int)sizeof(tmp), "Expecting encryption to be %d bytes long but was %d\n", (int)sizeof(unsigned short), len);
 				errorf(tmp);
 			} else
-				ies->encmethods = ntohs(get_uint16(data + 2));
+				ies->encmethods = ntohs(get_unaligned_uint16(data + 2));
 			break;
 		case IAX_IE_CHALLENGE:
 			ies->challenge = data + 2;
@@ -670,21 +655,21 @@ int iax_parse_ies(struct iax_ies *ies, unsigned char *data, int datalen)
 				snprintf(tmp, (int)sizeof(tmp),  "Expecting refresh to be %d bytes long but was %d\n", (int)sizeof(unsigned short), len);
 				errorf(tmp);
 			} else
-				ies->refresh = ntohs(get_uint16(data + 2));
+				ies->refresh = ntohs(get_unaligned_uint16(data + 2));
 			break;
 		case IAX_IE_DPSTATUS:
 			if (len != (int)sizeof(unsigned short)) {
 				snprintf(tmp, (int)sizeof(tmp),  "Expecting dpstatus to be %d bytes long but was %d\n", (int)sizeof(unsigned short), len);
 				errorf(tmp);
 			} else
-				ies->dpstatus = ntohs(get_uint16(data + 2));
+				ies->dpstatus = ntohs(get_unaligned_uint16(data + 2));
 			break;
 		case IAX_IE_CALLNO:
 			if (len != (int)sizeof(unsigned short)) {
 				snprintf(tmp, (int)sizeof(tmp),  "Expecting callno to be %d bytes long but was %d\n", (int)sizeof(unsigned short), len);
 				errorf(tmp);
 			} else
-				ies->callno = ntohs(get_uint16(data + 2));
+				ies->callno = ntohs(get_unaligned_uint16(data + 2));
 			break;
 		case IAX_IE_CAUSE:
 			ies->cause = data + 2;
@@ -710,7 +695,7 @@ int iax_parse_ies(struct iax_ies *ies, unsigned char *data, int datalen)
 				snprintf(tmp, (int)sizeof(tmp), "Expecting msgcount to be %d bytes long but was %d\n", (int)sizeof(unsigned short), len);
 				errorf(tmp);
 			} else
-				ies->msgcount = ntohs(get_uint16(data + 2));	
+				ies->msgcount = ntohs(get_unaligned_uint16(data + 2));	
 			break;
 		case IAX_IE_AUTOANSWER:
 			ies->autoanswer = 1;
@@ -723,21 +708,21 @@ int iax_parse_ies(struct iax_ies *ies, unsigned char *data, int datalen)
 				snprintf(tmp, (int)sizeof(tmp), "Expecting transferid to be %d bytes long but was %d\n", (int)sizeof(unsigned int), len);
 				errorf(tmp);
 			} else
-				ies->transferid = ntohl(get_uint32(data + 2));
+				ies->transferid = ntohl(get_unaligned_uint32(data + 2));
 			break;
 		case IAX_IE_DATETIME:
 			if (len != (int)sizeof(unsigned int)) {
 				snprintf(tmp, (int)sizeof(tmp), "Expecting date/time to be %d bytes long but was %d\n", (int)sizeof(unsigned int), len);
 				errorf(tmp);
 			} else
-				ies->datetime = ntohl(get_uint32(data + 2));
+				ies->datetime = ntohl(get_unaligned_uint32(data + 2));
 			break;
 		case IAX_IE_FIRMWAREVER:
 			if (len != (int)sizeof(unsigned short)) {
 				snprintf(tmp, (int)sizeof(tmp), "Expecting firmwarever to be %d bytes long but was %d\n", (int)sizeof(unsigned short), len);
 				errorf(tmp);
 			} else
-				ies->firmwarever = ntohs(get_uint16(data + 2));	
+				ies->firmwarever = ntohs(get_unaligned_uint16(data + 2));	
 			break;
 		case IAX_IE_DEVICETYPE:
 			ies->devicetype = data + 2;
@@ -750,7 +735,7 @@ int iax_parse_ies(struct iax_ies *ies, unsigned char *data, int datalen)
 				snprintf(tmp, (int)sizeof(tmp), "Expected block desc to be %d bytes long but was %d\n", (int)sizeof(unsigned int), len);
 				errorf(tmp);
 			} else
-				ies->fwdesc = ntohl(get_uint32(data + 2));
+				ies->fwdesc = ntohl(get_unaligned_uint32(data + 2));
 			break;
 		case IAX_IE_FWBLOCKDATA:
 			ies->fwdata = data + 2;
@@ -766,7 +751,7 @@ int iax_parse_ies(struct iax_ies *ies, unsigned char *data, int datalen)
 				errorf(tmp);
 			} else {
 				ies->provverpres = 1;
-				ies->provver = ntohl(get_uint32(data + 2));
+				ies->provver = ntohl(get_unaligned_uint32(data + 2));
 			}
 			break;
 		case IAX_IE_CALLINGPRES:
@@ -790,14 +775,14 @@ int iax_parse_ies(struct iax_ies *ies, unsigned char *data, int datalen)
 				snprintf(tmp, (int)sizeof(tmp), "Expecting callingtns to be %d bytes long but was %d\n", (int)sizeof(unsigned short), len);
 				errorf(tmp);
 			} else
-				ies->calling_tns = ntohs(get_uint16(data + 2));	
+				ies->calling_tns = ntohs(get_unaligned_uint16(data + 2));	
 			break;
                case IAX_IE_RR_JITTER:
                        if (len != (int)sizeof(unsigned int)) {
                                snprintf(tmp, (int)sizeof(tmp), "Expected jitter rr to be %d bytes long but was %d\n", (int)sizeof(unsigned int), len);
                                errorf(tmp);
                        } else {
-                               ies->rr_jitter = ntohl(get_uint32(data + 2));
+                               ies->rr_jitter = ntohl(get_unaligned_uint32(data + 2));
                        }
                        break;
                case IAX_IE_RR_LOSS:
@@ -805,7 +790,7 @@ int iax_parse_ies(struct iax_ies *ies, unsigned char *data, int datalen)
                                snprintf(tmp, (int)sizeof(tmp), "Expected loss rr to be %d bytes long but was %d\n", (int)sizeof(unsigned int), len);
                                errorf(tmp);
                        } else {
-                               ies->rr_loss = ntohl(get_uint32(data + 2));
+                               ies->rr_loss = ntohl(get_unaligned_uint32(data + 2));
                        }
                        break;
                case IAX_IE_RR_PKTS:
@@ -813,7 +798,7 @@ int iax_parse_ies(struct iax_ies *ies, unsigned char *data, int datalen)
                                snprintf(tmp, (int)sizeof(tmp), "Expected packets rr to be %d bytes long but was %d\n", (int)sizeof(unsigned int), len);
                                errorf(tmp);
                        } else {
-                               ies->rr_pkts = ntohl(get_uint32(data + 2));
+                               ies->rr_pkts = ntohl(get_unaligned_uint32(data + 2));
                        }
                        break;
                case IAX_IE_RR_DELAY:
@@ -821,7 +806,7 @@ int iax_parse_ies(struct iax_ies *ies, unsigned char *data, int datalen)
                                snprintf(tmp, (int)sizeof(tmp), "Expected loss rr to be %d bytes long but was %d\n", (int)sizeof(unsigned short), len);
                         errorf(tmp);
                        } else {
-                               ies->rr_delay = ntohs(get_uint16(data + 2));
+                               ies->rr_delay = ntohs(get_unaligned_uint16(data + 2));
                        }
                        break;
 		case IAX_IE_RR_DROPPED:
@@ -829,7 +814,7 @@ int iax_parse_ies(struct iax_ies *ies, unsigned char *data, int datalen)
 				snprintf(tmp, (int)sizeof(tmp), "Expected packets rr to be %d bytes long but was %d\n", (int)sizeof(unsigned int), len);
 				errorf(tmp);
 			} else {
-				ies->rr_dropped = ntohl(get_uint32(data + 2));
+				ies->rr_dropped = ntohl(get_unaligned_uint32(data + 2));
 			}
 			break;
 		case IAX_IE_RR_OOO:
@@ -837,7 +822,7 @@ int iax_parse_ies(struct iax_ies *ies, unsigned char *data, int datalen)
 				snprintf(tmp, (int)sizeof(tmp), "Expected packets rr to be %d bytes long but was %d\n", (int)sizeof(unsigned int), len);
 				errorf(tmp);
 			} else {
-				ies->rr_ooo = ntohl(get_uint32(data + 2));
+				ies->rr_ooo = ntohl(get_unaligned_uint32(data + 2));
 			}
 			break;
 		default:
diff --git a/dns.c b/dns.c
index 359fd9e8eb..807d2c279a 100755
--- a/dns.c
+++ b/dns.c
@@ -19,12 +19,13 @@
 #include <asterisk/logger.h>
 #include <asterisk/channel.h>
 #include <asterisk/dns.h>
+#include <asterisk/endian.h>
 
 #define MAX_SIZE 4096
 
 typedef struct {
 	unsigned	id :16;		/* query identification number */
-#if BYTE_ORDER == BIG_ENDIAN
+#if __BYTE_ORDER == __BIG_ENDIAN
 			/* fields in third byte */
 	unsigned	qr: 1;		/* response flag */
 	unsigned	opcode: 4;	/* purpose of message */
@@ -38,7 +39,7 @@ typedef struct {
 	unsigned	cd: 1;		/* checking disabled by resolver */
 	unsigned	rcode :4;	/* response code */
 #endif
-#if BYTE_ORDER == LITTLE_ENDIAN || BYTE_ORDER == PDP_ENDIAN
+#if __BYTE_ORDER == __LITTLE_ENDIAN || __BYTE_ORDER == __PDP_ENDIAN
 			/* fields in third byte */
 	unsigned	rd :1;		/* recursion desired */
 	unsigned	tc :1;		/* truncated message */
diff --git a/formats/format_g726.c b/formats/format_g726.c
index d549823c85..0371a75589 100755
--- a/formats/format_g726.c
+++ b/formats/format_g726.c
@@ -16,6 +16,7 @@
 #include <asterisk/logger.h>
 #include <asterisk/sched.h>
 #include <asterisk/module.h>
+#include <asterisk/endian.h>
 #include <netinet/in.h>
 #include <arpa/inet.h>
 #include <stdlib.h>
@@ -24,15 +25,6 @@
 #include <unistd.h>
 #include <errno.h>
 #include <string.h>
-#ifdef __linux__
-#include <endian.h>
-#else
-#ifdef SOLARIS
-#include "solaris-compat/compat.h"
-#else
-#include <machine/endian.h>
-#endif
-#endif
 
 #define	RATE_40		0
 #define	RATE_32		1
diff --git a/formats/format_g729.c b/formats/format_g729.c
index 5e79c00e1e..46fd0953fb 100755
--- a/formats/format_g729.c
+++ b/formats/format_g729.c
@@ -17,6 +17,7 @@
 #include <asterisk/logger.h>
 #include <asterisk/sched.h>
 #include <asterisk/module.h>
+#include <asterisk/endian.h>
 #include <netinet/in.h>
 #include <arpa/inet.h>
 #include <stdlib.h>
@@ -25,15 +26,6 @@
 #include <unistd.h>
 #include <errno.h>
 #include <string.h>
-#ifdef __linux__
-#include <endian.h>
-#else
-#ifdef SOLARIS
-#include "solaris-compat/compat.h"
-#else
-#include <machine/endian.h>
-#endif
-#endif
 
 /* Some Ideas for this code came from makeg729e.c by Jeffrey Chilton */
 
diff --git a/formats/format_gsm.c b/formats/format_gsm.c
index 8c3f2d517d..c4a63aa683 100755
--- a/formats/format_gsm.c
+++ b/formats/format_gsm.c
@@ -17,6 +17,7 @@
 #include <asterisk/logger.h>
 #include <asterisk/sched.h>
 #include <asterisk/module.h>
+#include <asterisk/endian.h>
 #include <netinet/in.h>
 #include <arpa/inet.h>
 #include <stdlib.h>
@@ -25,15 +26,6 @@
 #include <unistd.h>
 #include <errno.h>
 #include <string.h>
-#ifdef __linux__
-#include <endian.h>
-#else
-#ifdef SOLARIS
-#include "solaris-compat/compat.h"
-#else
-#include <machine/endian.h>
-#endif
-#endif
 #include "msgsm.h"
 
 /* Some Ideas for this code came from makegsme.c by Jeffrey Chilton */
diff --git a/formats/format_h263.c b/formats/format_h263.c
index 17805b2318..a676cf8fbf 100755
--- a/formats/format_h263.c
+++ b/formats/format_h263.c
@@ -17,6 +17,7 @@
 #include <asterisk/logger.h>
 #include <asterisk/sched.h>
 #include <asterisk/module.h>
+#include <asterisk/endian.h>
 #include <netinet/in.h>
 #include <arpa/inet.h>
 #include <stdlib.h>
@@ -25,15 +26,6 @@
 #include <unistd.h>
 #include <errno.h>
 #include <string.h>
-#ifdef __linux__
-#include <endian.h>
-#else
-#ifdef SOLARIS
-#include "solaris-compat/compat.h"
-#else
-#include <machine/endian.h>
-#endif
-#endif
 
 /* Some Ideas for this code came from makeh263e.c by Jeffrey Chilton */
 
diff --git a/formats/format_ilbc.c b/formats/format_ilbc.c
index 571e74d676..c340994612 100755
--- a/formats/format_ilbc.c
+++ b/formats/format_ilbc.c
@@ -19,6 +19,7 @@
 #include <asterisk/logger.h>
 #include <asterisk/sched.h>
 #include <asterisk/module.h>
+#include <asterisk/endian.h>
 #include <netinet/in.h>
 #include <arpa/inet.h>
 #include <stdlib.h>
@@ -27,15 +28,6 @@
 #include <unistd.h>
 #include <errno.h>
 #include <string.h>
-#ifdef __linux__
-#include <endian.h>
-#else
-#ifdef SOLARIS
-#include "solaris-compat/compat.h"
-#else
-#include <machine/endian.h>
-#endif
-#endif
 
 /* Some Ideas for this code came from makeg729e.c by Jeffrey Chilton */
 
diff --git a/formats/format_jpeg.c b/formats/format_jpeg.c
index b084030096..d750e567ee 100755
--- a/formats/format_jpeg.c
+++ b/formats/format_jpeg.c
@@ -19,6 +19,7 @@
 #include <asterisk/module.h>
 #include <asterisk/image.h>
 #include <asterisk/lock.h>
+#include <asterisk/endian.h>
 #include <netinet/in.h>
 #include <arpa/inet.h>
 #include <stdlib.h>
@@ -27,15 +28,6 @@
 #include <unistd.h>
 #include <errno.h>
 #include <string.h>
-#ifdef __linux__
-#include <endian.h>
-#else
-#ifdef SOLARIS
-#include "solaris-compat/compat.h"
-#else
-#include <machine/endian.h>
-#endif
-#endif
 
 
 static char *desc = "JPEG (Joint Picture Experts Group) Image Format";
diff --git a/formats/format_pcm.c b/formats/format_pcm.c
index 14edd0bb6a..79f5f226aa 100755
--- a/formats/format_pcm.c
+++ b/formats/format_pcm.c
@@ -17,6 +17,7 @@
 #include <asterisk/logger.h>
 #include <asterisk/sched.h>
 #include <asterisk/module.h>
+#include <asterisk/endian.h>
 #include <netinet/in.h>
 #include <arpa/inet.h>
 #include <stdlib.h>
@@ -25,15 +26,6 @@
 #include <unistd.h>
 #include <errno.h>
 #include <string.h>
-#ifdef __linux__
-#include <endian.h>
-#else
-#ifdef SOLARIS
-#include "solaris-compat/compat.h"
-#else
-#include <machine/endian.h>
-#endif
-#endif
 
 #define BUF_SIZE 160		/* 160 samples */
 
diff --git a/formats/format_pcm_alaw.c b/formats/format_pcm_alaw.c
index b677bb6fef..b5f27be39d 100755
--- a/formats/format_pcm_alaw.c
+++ b/formats/format_pcm_alaw.c
@@ -17,6 +17,7 @@
 #include <asterisk/logger.h>
 #include <asterisk/sched.h>
 #include <asterisk/module.h>
+#include <asterisk/endian.h>
 #include <netinet/in.h>
 #include <arpa/inet.h>
 #include <stdlib.h>
@@ -27,15 +28,6 @@
 #include <unistd.h>
 #include <errno.h>
 #include <string.h>
-#ifdef __linux__
-#include <endian.h>
-#else
-#ifdef SOLARIS
-#include "solaris-compat/compat.h"
-#else
-#include <machine/endian.h>
-#endif
-#endif
 
 #define BUF_SIZE 160		/* 160 samples */
 
diff --git a/formats/format_sln.c b/formats/format_sln.c
index d1826a3665..4c0b1bc523 100755
--- a/formats/format_sln.c
+++ b/formats/format_sln.c
@@ -15,6 +15,7 @@
 #include <asterisk/logger.h>
 #include <asterisk/sched.h>
 #include <asterisk/module.h>
+#include <asterisk/endian.h>
 #include <netinet/in.h>
 #include <arpa/inet.h>
 #include <stdlib.h>
@@ -23,15 +24,6 @@
 #include <unistd.h>
 #include <errno.h>
 #include <string.h>
-#ifdef __linux__
-#include <endian.h>
-#else
-#ifdef SOLARIS
-#include "solaris-compat/compat.h"
-#else
-#include <machine/endian.h>
-#endif
-#endif
 
 #define BUF_SIZE 320		/* 320 samples */
 
diff --git a/formats/format_vox.c b/formats/format_vox.c
index 7601994fd5..3413a4aa22 100755
--- a/formats/format_vox.c
+++ b/formats/format_vox.c
@@ -17,6 +17,7 @@
 #include <asterisk/logger.h>
 #include <asterisk/sched.h>
 #include <asterisk/module.h>
+#include <asterisk/endian.h>
 #include <netinet/in.h>
 #include <arpa/inet.h>
 #include <stdlib.h>
@@ -25,15 +26,6 @@
 #include <unistd.h>
 #include <errno.h>
 #include <string.h>
-#ifdef __linux__
-#include <endian.h>
-#else
-#ifdef SOLARIS
-#include "solaris-compat/compat.h"
-#else
-#include <machine/endian.h>
-#endif
-#endif
 
 #define BUF_SIZE 80		/* 160 samples */
 
diff --git a/formats/format_wav.c b/formats/format_wav.c
index c0781f6f03..66b82d468a 100755
--- a/formats/format_wav.c
+++ b/formats/format_wav.c
@@ -17,6 +17,7 @@
 #include <asterisk/logger.h>
 #include <asterisk/sched.h>
 #include <asterisk/module.h>
+#include <asterisk/endian.h>
 #include <netinet/in.h>
 #include <arpa/inet.h>
 #include <stdlib.h>
@@ -25,15 +26,6 @@
 #include <unistd.h>
 #include <errno.h>
 #include <string.h>
-#ifdef __linux__
-#include <endian.h>
-#else
-#ifdef SOLARIS
-#include "solaris-compat/compat.h"
-#else
-#include <machine/endian.h>
-#endif
-#endif
 
 /* Some Ideas for this code came from makewave.c by Jeffrey Chilton */
 
diff --git a/formats/format_wav_gsm.c b/formats/format_wav_gsm.c
index b1a0c1c1e6..fcd4c2ac21 100755
--- a/formats/format_wav_gsm.c
+++ b/formats/format_wav_gsm.c
@@ -17,6 +17,7 @@
 #include <asterisk/logger.h>
 #include <asterisk/sched.h>
 #include <asterisk/module.h>
+#include <asterisk/endian.h>
 #include <netinet/in.h>
 #include <arpa/inet.h>
 #include <stdlib.h>
@@ -25,15 +26,6 @@
 #include <unistd.h>
 #include <errno.h>
 #include <string.h>
-#ifdef __linux__
-#include <endian.h>
-#else
-#ifdef SOLARIS
-#include "solaris-compat/compat.h"
-#else
-#include <machine/endian.h>
-#endif
-#endif
 #include "msgsm.h"
 
 /* Some Ideas for this code came from makewave.c by Jeffrey Chilton */
diff --git a/include/asterisk/endian.h b/include/asterisk/endian.h
new file mode 100755
index 0000000000..66f7962509
--- /dev/null
+++ b/include/asterisk/endian.h
@@ -0,0 +1,50 @@
+/*
+ * Asterisk -- A telephony toolkit for Linux.
+ *
+ * Asterisk internal frame definitions.
+ * 
+ * Copyright (C) 1999 - 2005, Digium, Inc.
+ *
+ * Mark Spencer <markster@digium.com>
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU Lesser General Public License.  Other components of
+ * Asterisk are distributed under The GNU General Public License
+ * only.
+ */
+
+#ifndef _ASTERISK_ENDIAN_H
+#define _ASTERISK_ENDIAN_H
+
+/*
+ * Autodetect system endianess
+ */
+
+#if defined( __OpenBSD__ )
+#  include <machine/types.h>
+#  include <sys/endian.h>
+#elif defined( __FreeBSD__ ) || defined( __NetBSD__ )
+#  include <sys/types.h>
+#  include <sys/endian.h>
+#elif defined( BSD ) && ( BSD >= 199103 ) || defined(__APPLE__)
+#  include <machine/endian.h>
+#elif defined ( SOLARIS )
+#  include <solaris-compat/compat.h>
+#elif defined( __GNUC__ ) || defined( __GNU_LIBRARY__ )
+#  include <endian.h>
+#if !defined(__APPLE__)
+#  include <byteswap.h>
+#endif
+#elif defined( linux )
+#  include <endian.h>
+#endif
+
+#ifndef BYTE_ORDER
+#define BYTE_ORDER __BYTE_ORDER
+#endif
+
+#ifndef __BYTE_ORDER
+#error Endianess needs to be defined
+#endif
+#endif /* _ASTERISK_ENDIAN_H */
+
diff --git a/include/asterisk/frame.h b/include/asterisk/frame.h
index 4e7ef0343c..2edf248a3b 100755
--- a/include/asterisk/frame.h
+++ b/include/asterisk/frame.h
@@ -22,45 +22,7 @@ extern "C" {
 
 #include <sys/types.h>
 #include <sys/time.h>
-
-#ifdef SOLARIS
-#include "solaris-compat/compat.h"
-#endif
-	
-/*
- * Autodetect system endianess
- */
-#ifndef __BYTE_ORDER
-#ifdef __linux__
-#include <endian.h>
-#elif defined(__OpenBSD__) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__APPLE__)
-#if defined(__OpenBSD__)
-#include <machine/types.h>
-#endif /* __OpenBSD__ */
-#include <machine/endian.h>
-#define __BYTE_ORDER BYTE_ORDER
-#define __LITTLE_ENDIAN LITTLE_ENDIAN
-#define __BIG_ENDIAN BIG_ENDIAN
-#else
-#ifdef __LITTLE_ENDIAN__
-#define __BYTE_ORDER __LITTLE_ENDIAN
-#endif /* __LITTLE_ENDIAN */
-
-#if defined(i386) || defined(__i386__)
-#define __BYTE_ORDER __LITTLE_ENDIAN
-#endif /* defined i386 */
-
-#if defined(sun) && defined(unix) && defined(sparc)
-#define __BYTE_ORDER __BIG_ENDIAN
-#endif /* sun unix sparc */
-
-#endif /* linux */
-
-#endif /* __BYTE_ORDER */
-
-#ifndef __BYTE_ORDER
-#error Need to know endianess
-#endif /* __BYTE_ORDER */
+#include <asterisk/endian.h>
 
 struct ast_codec_pref {
 	char order[32];
diff --git a/include/asterisk/unaligned.h b/include/asterisk/unaligned.h
new file mode 100755
index 0000000000..fc012049ff
--- /dev/null
+++ b/include/asterisk/unaligned.h
@@ -0,0 +1,95 @@
+/*
+ * Asterisk -- A telephony toolkit for Linux.
+ *
+ * Asterisk internal frame definitions.
+ * 
+ * Copyright (C) 1999 - 2005, Digium, Inc.
+ *
+ * Mark Spencer <markster@digium.com>
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU Lesser General Public License.  Other components of
+ * Asterisk are distributed under The GNU General Public License
+ * only.
+ */
+
+#ifndef _ASTERISK_UNALIGNED_H
+#define _ASTERISK_UNALIGNED_H
+
+#if defined(__cplusplus) || defined(c_plusplus)
+extern "C" {
+#endif
+
+#ifdef __GNUC__
+/* If we just tell GCC what's going on, we can trust it to behave optimally */
+static inline unsigned int get_unaligned_uint32(void *p)
+{
+	struct { unsigned int d; } __attribute__((packed)) *pp = (void *)p;
+
+	return pp->d;
+}
+static inline unsigned short get_unaligned_uint16(void *p)
+{
+	struct { unsigned short d; } __attribute__((packed)) *pp = (void *)p;
+
+	return pp->d;
+}
+
+static inline void put_unaligned_uint32(void *p, unsigned int datum)
+{
+	struct { unsigned int d; } __attribute__((packed)) *pp = (void *)p;
+
+	pp->d = datum;
+}
+
+static inline void put_unaligned_uint16(void *p, unsigned short datum)
+{
+	struct { unsigned short d; } __attribute__((packed)) *pp = (void *)p;
+
+	pp->d = datum;
+}
+#elif defined(SOLARIS) && defined(__sparc__)
+static inline unsigned int get_unaligned_uint32(void *p)
+{
+	unsigned char *cp = p;
+
+	return (cp[0] << 24) | (cp[1] << 16) | (cp[2] << 8) | cp[3];
+}
+
+static inline unsigned short get_unaligned_uint16(void *p)
+{
+	unsigned char *cp = p;
+
+	return (cp[0] << 8) | cp[1] ;
+}
+
+static inline void put_unaligned_uint32(void *p, unsigned int datum)
+{
+	unsigned char *cp = p;
+
+	cp[0] = datum >> 24;
+	cp[1] = datum >> 16;
+	cp[2] = datum >> 8;
+	cp[3] = datum;
+}
+
+static inline void put_unaligned_uint16(void *p, unsigned int datum)
+{
+	unsigned char *cp = p;
+
+	cp[0] = datum >> 8;
+	cp[1] = datum;
+}
+#else /* Not GCC, not Solaris/SPARC. Assume we can handle direct load/store. */
+#define get_unaligned_uint32(p) (*((unsigned int *)(p)))
+#define get_unaligned_uint16(p) (*((unsigned short *)(p)))
+#define put_unaligned_uint32(p,d) do { unsigned int *__P = (p); *__P = d; } while(0)
+#define put_unaligned_uint16(p,d) do { unsigned short *__P = (p); *__P = d; } while(0)
+#endif
+
+#if defined(__cplusplus) || defined(c_plusplus)
+}
+#endif
+
+
+#endif /* _ASTERISK_UNALIGNED_H */
diff --git a/md5.c b/md5.c
index d39e0fe1a2..c60652c008 100755
--- a/md5.c
+++ b/md5.c
@@ -1,22 +1,5 @@
 /* MD5 checksum routines used for authentication.  Not covered by GPL, but
    in the public domain as per the copyright below */
-#if defined( __OpenBSD__ )
-#  include <machine/types.h>
-#  include <sys/endian.h>
-#elif defined( __FreeBSD__ ) || defined( __NetBSD__ )
-#  include <sys/types.h>
-#  include <sys/endian.h>
-#elif defined( BSD ) && ( BSD >= 199103 ) || defined(__APPLE__)
-#  include <machine/endian.h>
-#elif defined( __sparc__ ) && defined( SOLARIS )
-#  define BIG_ENDIAN 4321
-#  define BYTE_ORDER BIG_ENDIAN
-#else
-#  include <endian.h>
-#endif
-# if __BYTE_ORDER == __BIG_ENDIAN || BYTE_ORDER == BIG_ENDIAN
-#  define HIGHFIRST 1
-# endif
 
 /*
  * This code implements the MD5 message-digest algorithm.
@@ -35,8 +18,12 @@
  * will fill a supplied 16-byte array with the digest.
  */
 #include <string.h>		/* for memcpy() */
+#include <asterisk/endian.h>
 #include <asterisk/md5.h>
 
+# if __BYTE_ORDER == __BIG_ENDIAN
+#  define HIGHFIRST 1
+# endif
 #ifndef HIGHFIRST
 #define byteReverse(buf, len)	/* Nothing */
 #else
diff --git a/rtp.c b/rtp.c
index 80484fc417..d5c6b99bc9 100755
--- a/rtp.c
+++ b/rtp.c
@@ -37,6 +37,7 @@
 #include <asterisk/lock.h>
 #include <asterisk/utils.h>
 #include <asterisk/cli.h>
+#include <asterisk/unaligned.h>
 
 #define MAX_TIMESTAMP_SKEW	640
 
@@ -1173,18 +1174,6 @@ int ast_rtp_sendcng(struct ast_rtp *rtp, int level)
 	return 0;
 }
 
-#if defined(SOLARIS) && defined(__sparc__)
-static void put_uint32(unsigned char *buf, int i)
-{
-	buf[0] = (i>>24) & 0xff;
-	buf[1] = (i>>16) & 0xff;
-	buf[2] = (i>>8)  & 0xff;
-	buf[3] = i       & 0xff;
-}
-#else
-#define put_uint32(p,v) ((*((unsigned int *)(p))) = (v))
-#endif
-
 static int ast_rtp_raw_write(struct ast_rtp *rtp, struct ast_frame *f, int codec)
 {
 	unsigned char *rtpheader;
@@ -1270,9 +1259,9 @@ static int ast_rtp_raw_write(struct ast_rtp *rtp, struct ast_frame *f, int codec
 	/* Get a pointer to the header */
 	rtpheader = (unsigned char *)(f->data - hdrlen);
 
-	put_uint32(rtpheader, htonl((2 << 30) | (codec << 16) | (rtp->seqno) | (mark << 23)));
-	put_uint32(rtpheader + 4, htonl(rtp->lastts));
-	put_uint32(rtpheader + 8, htonl(rtp->ssrc)); 
+	put_unaligned_uint32(rtpheader, htonl((2 << 30) | (codec << 16) | (rtp->seqno) | (mark << 23)));
+	put_unaligned_uint32(rtpheader + 4, htonl(rtp->lastts));
+	put_unaligned_uint32(rtpheader + 8, htonl(rtp->ssrc)); 
 
 	if (rtp->them.sin_port && rtp->them.sin_addr.s_addr) {
 		res = sendto(rtp->s, (void *)rtpheader, f->datalen + hdrlen, 0, (struct sockaddr *)&rtp->them, sizeof(rtp->them));
-- 
GitLab