Index: pbx/dundi-parser.c
===================================================================
--- pbx/dundi-parser.c	(revision 95361)
+++ pbx/dundi-parser.c	(working copy)
@@ -32,7 +32,9 @@
 
 #include "asterisk/frame.h"
 #include "asterisk/utils.h"
+#include "asterisk/unaligned.h"
 #include "asterisk/dundi.h"
+
 #include "dundi-parser.h"
 
 static void internaloutput(const char *str)
@@ -669,158 +671,167 @@
 int dundi_parse_ies(struct dundi_ies *ies, unsigned char *data, int datalen)
 {
 	/* Parse data into information elements */
-	int len;
-	int ie;
 	char tmp[256];
+	struct {
+		char ie;
+		unsigned char len;
+		union {
+			char str[255];
+			unsigned char byte;
+			struct dundi_eid *d_eid;
+			struct dundi_answer *d_answer;
+			struct dundi_hint *d_hint;
+			struct dundi_encblock *d_encblock;
+			int value;
+		} ata;
+	} *d = (void *)data;
 	memset(ies, 0, (int)sizeof(struct dundi_ies));
 	ies->ttl = -1;
 	ies->expiration = -1;
 	ies->unknowncmd = -1;
 	ies->cause = -1;
 	while(datalen >= 2) {
-		ie = data[0];
-		len = data[1];
-		if (len > datalen - 2) {
+		if(d->len > datalen -2){
 			errorf("Information element length exceeds message size\n");
 			return -1;
 		}
-		switch(ie) {
+		switch(d->ie) {
 		case DUNDI_IE_EID:
 		case DUNDI_IE_EID_DIRECT:
-			if (len != (int)sizeof(dundi_eid)) {
+			if (d->len != (int)sizeof(dundi_eid)) {
 				errorf("Improper entity identifer, expecting 6 bytes!\n");
 			} else if (ies->eidcount < DUNDI_MAX_STACK) {
 				ies->eids[ies->eidcount] = (dundi_eid *)(data + 2);
-				ies->eid_direct[ies->eidcount] = (ie == DUNDI_IE_EID_DIRECT);
+				ies->eid_direct[ies->eidcount] = (d->ie == DUNDI_IE_EID_DIRECT);
 				ies->eidcount++;
 			} else
 				errorf("Too many entities in stack!\n");
 			break;
 		case DUNDI_IE_REQEID:
-			if (len != (int)sizeof(dundi_eid)) {
+			if (d->len != (int)sizeof(dundi_eid)) {
 				errorf("Improper requested entity identifer, expecting 6 bytes!\n");
 			} else
-				ies->reqeid = (dundi_eid *)(data + 2);
+				ies->reqeid = d->ata.d_eid;
 			break;
 		case DUNDI_IE_CALLED_CONTEXT:
-			ies->called_context = (char *)data + 2;
+			ies->called_context = d->ata.str;
 			break;
 		case DUNDI_IE_CALLED_NUMBER:
-			ies->called_number = (char *)data + 2;
+			ies->called_number = d->ata.str;
 			break;
 		case DUNDI_IE_ANSWER:
-			if (len < sizeof(struct dundi_answer)) {
-				snprintf(tmp, (int)sizeof(tmp), "Answer expected to be >=%d bytes long but was %d\n", (int)sizeof(struct dundi_answer), len);
+			if (d->len < sizeof(struct dundi_answer)) {
+				snprintf(tmp, (int)sizeof(tmp), "Answer expected to be >=%d bytes long but was %d\n", (int)sizeof(struct dundi_answer), d->len);
 				errorf(tmp);
 			} else {
 				if (ies->anscount < DUNDI_MAX_ANSWERS)
-					ies->answers[ies->anscount++]= (struct dundi_answer *)(data + 2);
+					ies->answers[ies->anscount++]= d->ata.d_answer;
 				else 
 					errorf("Ignoring extra answers!\n");
 			}
 			break;
 		case DUNDI_IE_TTL:
-			if (len != (int)sizeof(unsigned short)) {
-				snprintf(tmp, (int)sizeof(tmp), "Expecting ttl to be %d bytes long but was %d\n", (int)sizeof(unsigned short), len);
+			if (d->len != (int)sizeof(unsigned short)) {
+				snprintf(tmp, (int)sizeof(tmp), "Expecting ttl to be %d bytes long but was %d\n", (int)sizeof(unsigned short), d->len);
 				errorf(tmp);
 			} else
-				ies->ttl = ntohs(*((unsigned short *)(data + 2)));
+				ies->ttl = ntohs(get_unaligned_uint16(&d->ata.value));
 			break;
 		case DUNDI_IE_VERSION:
-			if (len != (int)sizeof(unsigned short)) {
-				snprintf(tmp, (int)sizeof(tmp),  "Expecting version to be %d bytes long but was %d\n", (int)sizeof(unsigned short), len);
+			if (d->len != (int)sizeof(unsigned short)) {
+				snprintf(tmp, (int)sizeof(tmp),  "Expecting version to be %d bytes long but was %d\n", (int)sizeof(unsigned short), d->len);
 				errorf(tmp);
 			} else
-				ies->version = ntohs(*((unsigned short *)(data + 2)));
+				ies->version = ntohs(get_unaligned_uint16(&d->ata.value));
 			break;
 		case DUNDI_IE_EXPIRATION:
-			if (len != (int)sizeof(unsigned short)) {
-				snprintf(tmp, (int)sizeof(tmp),  "Expecting expiration to be %d bytes long but was %d\n", (int)sizeof(unsigned short), len);
+			if (d->len != (int)sizeof(unsigned short)) {
+				snprintf(tmp, (int)sizeof(tmp),  "Expecting expiration to be %d bytes long but was %d\n", (int)sizeof(unsigned short), d->len);
 				errorf(tmp);
 			} else
-				ies->expiration = ntohs(*((unsigned short *)(data + 2)));
+				ies->expiration = ntohs(get_unaligned_uint16(&d->ata.value));
 			break;
 		case DUNDI_IE_KEYCRC32:
-			if (len != (int)sizeof(unsigned int)) {
-				snprintf(tmp, (int)sizeof(tmp),  "Expecting expiration to be %d bytes long but was %d\n", (int)sizeof(unsigned int), len);
+			if (d->len != (int)sizeof(unsigned int)) {
+				snprintf(tmp, (int)sizeof(tmp),  "Expecting expiration to be %d bytes long but was %d\n", (int)sizeof(unsigned int), d->len);
 				errorf(tmp);
 			} else
-				ies->keycrc32 = ntohl(*((unsigned int *)(data + 2)));
+				ies->keycrc32 = ntohl(get_unaligned_uint32(&d->ata.value));
 			break;
 		case DUNDI_IE_UNKNOWN:
-			if (len == 1)
-				ies->unknowncmd = data[2];
+			if (d->len == 1)
+				ies->unknowncmd = d->ata.byte;
 			else {
-				snprintf(tmp, (int)sizeof(tmp), "Expected single byte Unknown command, but was %d long\n", len);
+				snprintf(tmp, (int)sizeof(tmp), "Expected single byte Unknown command, but was %d long\n", d->len);
 				errorf(tmp);
 			}
 			break;
 		case DUNDI_IE_CAUSE:
-			if (len >= 1) {
-				ies->cause = data[2];
-				ies->causestr = (char *)data + 3;
+			if (d->len >= 1) {
+				ies->cause = d->ata.byte;
+				ies->causestr = d->ata.str + 1;
 			} else {
-				snprintf(tmp, (int)sizeof(tmp), "Expected at least one byte cause, but was %d long\n", len);
+				snprintf(tmp, (int)sizeof(tmp), "Expected at least one byte cause, but was %d long\n", d->len);
 				errorf(tmp);
 			}
 			break;
 		case DUNDI_IE_HINT:
-			if (len >= 2) {
-				ies->hint = (struct dundi_hint *)(data + 2);
+			if (d->len >= 2) {
+				ies->hint = d->ata.d_hint;
 			} else {
-				snprintf(tmp, (int)sizeof(tmp), "Expected at least two byte hint, but was %d long\n", len);
+				snprintf(tmp, (int)sizeof(tmp), "Expected at least two byte hint, but was %d long\n", d->len);
 				errorf(tmp);
 			}
 			break;
 		case DUNDI_IE_DEPARTMENT:
-			ies->q_dept = (char *)data + 2;
+			ies->q_dept = d->ata.str;
 			break;
 		case DUNDI_IE_ORGANIZATION:
-			ies->q_org = (char *)data + 2;
+			ies->q_org = d->ata.str;
 			break;
 		case DUNDI_IE_LOCALITY:
-			ies->q_locality = (char *)data + 2;
+			ies->q_locality = d->ata.str;
 			break;
 		case DUNDI_IE_STATE_PROV:
-			ies->q_stateprov = (char *)data + 2;
+			ies->q_stateprov = d->ata.str;
 			break;
 		case DUNDI_IE_COUNTRY:
-			ies->q_country = (char *)data + 2;
+			ies->q_country = d->ata.str;
 			break;
 		case DUNDI_IE_EMAIL:
-			ies->q_email = (char *)data + 2;
+			ies->q_email = d->ata.str;
 			break;
 		case DUNDI_IE_PHONE:
-			ies->q_phone = (char *)data + 2;
+			ies->q_phone = d->ata.str;
 			break;
 		case DUNDI_IE_IPADDR:
-			ies->q_ipaddr = (char *)data + 2;
+			ies->q_ipaddr = d->ata.str;
 			break;
 		case DUNDI_IE_ENCDATA:
 			/* Recalculate len as the remainder of the message, regardless of
 			   theoretical length */
-			len = datalen - 2;
-			if ((len > 16) && !(len % 16)) {
-				ies->encblock = (struct dundi_encblock *)(data + 2);
-				ies->enclen = len - 16;
+			d->len = datalen - 2;
+			if ((d->len > 16) && !(d->len % 16)) {
+				ies->encblock = d->ata.d_encblock;
+				ies->enclen = d->len - 16;
 			} else {
-				snprintf(tmp, (int)sizeof(tmp), "Invalid encrypted data length %d\n", len);
+				snprintf(tmp, (int)sizeof(tmp), "Invalid encrypted data length %d\n", d->len);
 				errorf(tmp);
 			}
 			break;
 		case DUNDI_IE_SHAREDKEY:
-			if (len == 128) {
-				ies->encsharedkey = (unsigned char *)(data + 2);
+			if (d->len == 128) {
+				ies->encsharedkey = (unsigned char *)d->ata.str;
 			} else {
-				snprintf(tmp, (int)sizeof(tmp), "Invalid encrypted shared key length %d\n", len);
+				snprintf(tmp, (int)sizeof(tmp), "Invalid encrypted shared key length %d\n", d->len);
 				errorf(tmp);
 			}
 			break;
 		case DUNDI_IE_SIGNATURE:
-			if (len == 128) {
-				ies->encsig = (unsigned char *)(data + 2);
+			if (d->len == 128) {
+				ies->encsig = (unsigned char *)d->ata.str;
 			} else {
-				snprintf(tmp, (int)sizeof(tmp), "Invalid encrypted signature length %d\n", len);
+				snprintf(tmp, (int)sizeof(tmp), "Invalid encrypted signature length %d\n", d->len);
 				errorf(tmp);
 			}
 			break;
@@ -828,16 +839,16 @@
 			ies->cbypass = 1;
 			break;
 		default:
-			snprintf(tmp, (int)sizeof(tmp), "Ignoring unknown information element '%s' (%d) of length %d\n", dundi_ie2str(ie), ie, len);
+			snprintf(tmp, (int)sizeof(tmp), "Ignoring unknown information element '%s' (%d) of length %d\n", dundi_ie2str(d->ie), d->ie, d->len);
 			outputf(tmp);
 		}
 		/* Overwrite information element with 0, to null terminate previous portion */
-		data[0] = 0;
-		datalen -= (len + 2);
-		data += (len + 2);
+		d->ie = 0;
+		datalen -= (d->len + 2);
+		d += (d->len + 2);
 	}
 	/* Null-terminate last field */
-	*data = '\0';
+	*d->ata.str = '\0';
 	if (datalen) {
 		errorf("Invalid information element contents, strange boundary\n");
 		return -1;
