From 700c53e60ab469d31f84791c8ce98a31f84981bc Mon Sep 17 00:00:00 2001
From: "Francisco Blas (klondike) Izquierdo Riera" <klondike@klondike.es>
Date: Tue, 30 Dec 2014 15:37:24 +0100
Subject: [PATCH] Fix any remaning aliasing rules with propper memcpy wrappers

---
 Datagram.cpp      |  2 +-
 Garlic.cpp        | 18 ++++++-------
 I2NPProtocol.cpp  | 14 +++++------
 I2PEndian.h       | 64 ++++++++++++++++++++++++++++++++++++++++-------
 Identity.cpp      |  4 +--
 NTCPSession.cpp   | 12 ++++-----
 SSUData.cpp       |  6 ++---
 SSUSession.cpp    | 44 ++++++++++++++++----------------
 Streaming.cpp     | 52 +++++++++++++++++++-------------------
 TransitTunnel.cpp |  2 +-
 TunnelGateway.cpp | 16 ++++++------
 11 files changed, 140 insertions(+), 94 deletions(-)

diff --git a/Datagram.cpp b/Datagram.cpp
index ec851ba7..410b9740 100644
--- a/Datagram.cpp
+++ b/Datagram.cpp
@@ -117,7 +117,7 @@ namespace datagram
 		compressor.MessageEnd();
 		int size = compressor.MaxRetrievable ();
 		uint8_t * buf = msg->GetPayload ();
-		*(uint32_t *)buf = htobe32 (size); // length
+		htobe32buf (buf, size); // length
 		buf += 4;
 		compressor.Get (buf, size);
 		memset (buf + 4, 0, 4); // source and destination are zeroes
diff --git a/Garlic.cpp b/Garlic.cpp
index 62fd010f..1948806b 100644
--- a/Garlic.cpp
+++ b/Garlic.cpp
@@ -138,7 +138,7 @@ namespace garlic
 		}	
 		// AES block
 		len += CreateAESBlock (buf, msg);
-		*(uint32_t *)(m->GetPayload ()) = htobe32 (len);
+		htobe32buf (m->GetPayload (), len);
 		m->len += len + 4;
 		FillI2NPMessageHeader (m, eI2NPGarlic);
 		if (msg)
@@ -151,7 +151,7 @@ namespace garlic
 		size_t blockSize = 0;
 		bool createNewTags = m_Owner && m_NumTags && ((int)m_SessionTags.size () <= m_NumTags/2);
 		UnconfirmedTags * newTags = createNewTags ? GenerateSessionTags () : nullptr;
-		*(uint16_t *)buf = newTags ? htobe16 (newTags->numTags) : 0; // tag count
+		htobuf16 (buf, newTags ? htobe16 (newTags->numTags) : 0); // tag count
 		blockSize += 2;
 		if (newTags) // session tags recreated
 		{	
@@ -220,9 +220,9 @@ namespace garlic
 		
 		memset (payload + size, 0, 3); // certificate of message
 		size += 3;
-		*(uint32_t *)(payload + size) = htobe32 (msgID); // MessageID
+		htobe32buf (payload + size, msgID); // MessageID
 		size += 4;
-		*(uint64_t *)(payload + size) = htobe64 (ts); // Expiration of message
+		htobe64buf (payload + size, ts); // Expiration of message
 		size += 8;
 		return size;
 	}	
@@ -246,9 +246,9 @@ namespace garlic
 		
 		memcpy (buf + size, msg->GetBuffer (), msg->GetLength ());
 		size += msg->GetLength ();
-		*(uint32_t *)(buf + size) = htobe32 (m_Rnd.GenerateWord32 ()); // CloveID
+		htobe32buf (buf + size, m_Rnd.GenerateWord32 ()); // CloveID
 		size += 4;
-		*(uint64_t *)(buf + size) = htobe64 (ts); // Expiration of clove
+		htobe64buf (buf + size, ts); // Expiration of clove
 		size += 8;
 		memset (buf + size, 0, 3); // certificate of clove
 		size += 3;
@@ -269,7 +269,7 @@ namespace garlic
 				// hash and tunnelID sequence is reversed for Garlic 
 				memcpy (buf + size, leases[i].tunnelGateway, 32); // To Hash
 				size += 32;
-				*(uint32_t *)(buf + size) = htobe32 (leases[i].tunnelID); // tunnelID
+				htobe32buf (buf + size, leases[i].tunnelID); // tunnelID
 				size += 4; 	
 				// create msg 
 				I2NPMessage * msg = CreateDeliveryStatusMsg (msgID);
@@ -288,9 +288,9 @@ namespace garlic
 				DeleteI2NPMessage (msg);
 				// fill clove
 				uint64_t ts = i2p::util::GetMillisecondsSinceEpoch () + 5000; // 5 sec
-				*(uint32_t *)(buf + size) = htobe32 (m_Rnd.GenerateWord32 ()); // CloveID
+				htobe32buf (buf + size, m_Rnd.GenerateWord32 ()); // CloveID
 				size += 4;
-				*(uint64_t *)(buf + size) = htobe64 (ts); // Expiration of clove
+				htobe64buf (buf + size, ts); // Expiration of clove
 				size += 8;
 				memset (buf + size, 0, 3); // certificate of clove
 				size += 3;
diff --git a/I2NPProtocol.cpp b/I2NPProtocol.cpp
index 95079260..f09abbd7 100644
--- a/I2NPProtocol.cpp
+++ b/I2NPProtocol.cpp
@@ -115,7 +115,7 @@ namespace i2p
 		if (replyTunnelID)
 		{
 			*buf = encryption ? 0x03: 0x01; // set delivery flag
-			*(uint32_t *)(buf+1) = htobe32 (replyTunnelID);
+			htobe32buf (buf+1, replyTunnelID);
 			buf += 5;
 		}
 		else
@@ -127,7 +127,7 @@ namespace i2p
 		
 		if (exploratory)
 		{
-			*(uint16_t *)buf = htobe16 (1); // one exlude record
+			htobe16buf (buf,1); // one exlude record
 			buf += 2;
 			// reply with non-floodfill routers only
 			memset (buf, 0, 32);
@@ -138,7 +138,7 @@ namespace i2p
 			if (excludedPeers)
 			{
 				int cnt = excludedPeers->size ();
-				*(uint16_t *)buf = htobe16 (cnt);
+				htobe16buf (buf, cnt);
 				buf += 2;
 				for (auto& it: *excludedPeers)
 				{
@@ -149,7 +149,7 @@ namespace i2p
 			else
 			{	
 				// nothing to exclude
-				*(uint16_t *)buf = htobe16 (0);
+				htobe16buf (buf, 0);
 				buf += 2;
 			}	
 		}	
@@ -210,7 +210,7 @@ namespace i2p
 		compressor.MessageEnd();
 		auto size = compressor.MaxRetrievable ();
 		uint8_t * buf = m->GetPayload () + sizeof (I2NPDatabaseStoreMsg);
-		*(uint16_t *)buf = htobe16 (size); // size
+		htobe16buf (buf, size); // size
 		buf += 2;
 		// TODO: check if size doesn't exceed buffer
 		compressor.Get (buf, size); 
@@ -235,7 +235,7 @@ namespace i2p
 			auto leases = leaseSet->GetNonExpiredLeases ();
 			if (leases.size () > 0)
 			{
-				*(uint32_t *)(payload + size) = htobe32 (leases[0].tunnelID);
+				htobe32buf (payload + size, leases[0].tunnelID);
 				size += 4; // reply tunnelID
 				memcpy (payload + size, leases[0].tunnelGateway, 32);
 				size += 32; // reply tunnel gateway
@@ -422,7 +422,7 @@ namespace i2p
 	{
 		I2NPMessage * msg = NewI2NPMessage ();
 		memcpy (msg->GetPayload () + 4, payload, i2p::tunnel::TUNNEL_DATA_MSG_SIZE - 4);
-		*(uint32_t *)(msg->GetPayload ()) = htobe32 (tunnelID);
+		htobe32buf (msg->GetPayload (), tunnelID);
 		msg->len += i2p::tunnel::TUNNEL_DATA_MSG_SIZE; 
 		FillI2NPMessageHeader (msg, eI2NPTunnelData);
 		return msg;
diff --git a/I2PEndian.h b/I2PEndian.h
index cff68669..d8be0f82 100644
--- a/I2PEndian.h
+++ b/I2PEndian.h
@@ -47,27 +47,73 @@ uint64_t be64toh(uint64_t big64);
 
 #endif
 
+inline uint16_t buf16toh(const uint8_t *buf)
+{
+	uint16_t b16;
+	memcpy(&b16, buf, sizeof(uint16_t));
+	return b16;
+}
+
+inline uint32_t buf32toh(const uint8_t *buf)
+{
+	uint32_t b32;
+	memcpy(&b32, buf, sizeof(uint32_t));
+	return b32;
+}
+
+inline uint64_t buf64toh(const uint8_t *buf)
+{
+	uint64_t b64;
+	memcpy(&b64, buf, sizeof(uint64_t));
+	return b64;
+}
+
 inline uint16_t bufbe16toh(const uint8_t *buf)
 {
-	uint16_t big16;
-	memcpy(&big16, buf, sizeof(uint16_t));
-	return be16toh(big16);
+	return be16toh(buf16toh(buf));
 }
 
 inline uint32_t bufbe32toh(const uint8_t *buf)
 {
-	uint32_t big32;
-	memcpy(&big32, buf, sizeof(uint32_t));
-	return be32toh(big32);
+	return be32toh(buf32toh(buf));
 }
 
 inline uint64_t bufbe64toh(const uint8_t *buf)
 {
-	uint64_t big64;
-	memcpy(&big64, buf, sizeof(uint64_t));
-	return be64toh(big64);
+	return be64toh(buf64toh(buf));
 }
 
+inline void htobuf16(uint8_t *buf, uint16_t b16)
+{
+	memcpy(buf, &b16, sizeof(uint16_t));
+}
+
+inline void htobuf32(uint8_t *buf, uint32_t b32)
+{
+	memcpy(buf, &b32, sizeof(uint32_t));
+}
+
+inline void htobuf64(uint8_t *buf, uint64_t b64)
+{
+	memcpy(buf, &b64, sizeof(uint64_t));
+}
+
+inline void htobe16buf(uint8_t *buf, uint16_t big16)
+{
+	htobuf16(buf, htobe16(big16));
+}
+
+inline void htobe32buf(uint8_t *buf, uint32_t big32)
+{
+	htobuf32(buf, htobe32(big32));
+}
+
+inline void htobe64buf(uint8_t *buf, uint64_t big64)
+{
+	htobuf64(buf, htobe64(big64));
+}
+
+
 
 #endif // I2PENDIAN_H__
 
diff --git a/Identity.cpp b/Identity.cpp
index e7d9afcb..52920f6b 100644
--- a/Identity.cpp
+++ b/Identity.cpp
@@ -101,8 +101,8 @@ namespace data
 			m_StandardIdentity.certificate.length = htobe16 (m_ExtendedLen); 
 			// fill extended buffer
 			m_ExtendedBuffer = new uint8_t[m_ExtendedLen];
-			*(uint16_t *)m_ExtendedBuffer = htobe16 (type);
-			*(uint16_t *)(m_ExtendedBuffer + 2) = htobe16 (CRYPTO_KEY_TYPE_ELGAMAL);
+			htobe16buf (m_ExtendedBuffer, type);
+			htobe16buf (m_ExtendedBuffer + 2, CRYPTO_KEY_TYPE_ELGAMAL);
 			if (excessLen && excessBuf)
 			{
 				memcpy (m_ExtendedBuffer + 4, excessBuf, excessLen);
diff --git a/NTCPSession.cpp b/NTCPSession.cpp
index f16264f4..3f326098 100644
--- a/NTCPSession.cpp
+++ b/NTCPSession.cpp
@@ -274,11 +274,11 @@ namespace transport
 	{
 		auto keys = i2p::context.GetPrivateKeys ();
 		uint8_t * buf = m_ReceiveBuffer; 
-		*(uint16_t *)buf = htobe16 (keys.GetPublic ().GetFullLen ());
+		htobe16buf (buf, keys.GetPublic ().GetFullLen ());
 		buf += 2;
 		buf += i2p::context.GetIdentity ().ToBuffer (buf, NTCP_BUFFER_SIZE);
 		uint32_t tsA = htobe32 (i2p::util::GetSecondsSinceEpoch ());
-		*(uint32_t *)buf = tsA;
+		htobuf32(buf,tsA);
 		buf += 4;		
 		size_t signatureLen = keys.GetPublic ().GetSignatureLen ();
 		size_t len = (buf - m_ReceiveBuffer) + signatureLen;
@@ -376,7 +376,7 @@ namespace transport
 	void NTCPSession::HandlePhase3 (uint32_t tsB, size_t paddingLen)
 	{
 		uint8_t * buf = m_ReceiveBuffer + m_RemoteIdentity.GetFullLen () + 2 /*size*/;
-		uint32_t tsA = *(uint32_t *)buf; 
+		uint32_t tsA = buf32toh(buf); 
 		buf += 4;
 		buf += paddingLen;	
 
@@ -580,15 +580,15 @@ namespace transport
 			}	
 			sendBuffer = msg->GetBuffer () - 2; 
 			len = msg->GetLength ();
-			*((uint16_t *)sendBuffer) = htobe16 (len);
+			htobe16buf (sendBuffer, len);
 		}	
 		else
 		{
 			// prepare timestamp
 			sendBuffer = m_TimeSyncBuffer;
 			len = 4;
-			*((uint16_t *)sendBuffer) = 0;
-			*((uint32_t *)(sendBuffer + 2)) = htobe32 (time (0));
+			htobuf16(sendBuffer, 0);
+			htobe32buf (sendBuffer + 2, time (0));
 		}	
 		int rem = (len + 6) & 0x0F; // %16
 		int padding = 0;
diff --git a/SSUData.cpp b/SSUData.cpp
index 596b7238..c6f0b5e5 100644
--- a/SSUData.cpp
+++ b/SSUData.cpp
@@ -316,7 +316,7 @@ namespace transport
 			payload++;
 			*payload = 1; // always 1 message fragment per message
 			payload++;
-			*(uint32_t *)payload = msgID;
+			htobuf32(payload, msgID);
 			payload += 4;
 			bool isLast = (len <= payloadSize);
 			size_t size = isLast ? len : payloadSize;
@@ -359,7 +359,7 @@ namespace transport
 		payload++;
 		*payload = 1; // number of ACKs
 		payload++;
-		*(uint32_t *)(payload) = htobe32 (msgID); // msgID	
+		htobe32buf (payload, msgID); // msgID	
 		payload += 4;
 		*payload = 0; // number of fragments
 
@@ -382,7 +382,7 @@ namespace transport
 		*payload = 1; // number of ACK bitfields
 		payload++;
 		// one ack
-		*(uint32_t *)(payload) = htobe32 (msgID); // msgID	
+		htobe32buf (payload, msgID); // msgID	
 		payload += 4;
 		div_t d = div (fragmentNum, 7);
 		memset (payload, 0x80, d.quot); // 0x80 means non-last
diff --git a/SSUSession.cpp b/SSUSession.cpp
index fffc232d..e8e82d9b 100644
--- a/SSUSession.cpp
+++ b/SSUSession.cpp
@@ -299,18 +299,18 @@ namespace transport
 	
 		uint8_t buf[96 + 18]; 
 		uint8_t * payload = buf + sizeof (SSUHeader);
-		*(uint32_t *)payload = htobe32 (iTag);
+		htobe32buf (payload, iTag);
 		payload += 4;
 		*payload = 0; // no address
 		payload++;
-		*(uint16_t *)payload = 0; // port = 0
+		htobuf16(payload, 0); // port = 0
 		payload += 2;
 		*payload = 0; // challenge
 		payload++;	
 		memcpy (payload, (const uint8_t *)address->key, 32);
 		payload += 32;
 		CryptoPP::RandomNumberGenerator& rnd = i2p::context.GetRandomNumberGenerator ();
-		*(uint32_t *)payload = htobe32 (rnd.GenerateWord32 ()); // nonce	
+		htobe32buf (payload, rnd.GenerateWord32 ()); // nonce	
 
 		uint8_t iv[16];
 		rnd.GenerateBlock (iv, 16); // random iv
@@ -358,7 +358,7 @@ namespace transport
 			s.Insert (payload, 16); // remote endpoint IP V6
 			payload += 16;
 		}
-		*(uint16_t *)(payload) = htobe16 (m_RemoteEndpoint.port ());
+		htobe16buf (payload, m_RemoteEndpoint.port ());
 		s.Insert (payload, 2); // remote port
 		payload += 2;
 		if (address->host.is_v4 ())
@@ -373,9 +373,9 @@ namespace transport
 			if (!relayTag) relayTag = 1;
 			m_Server.AddRelay (relayTag, m_RemoteEndpoint);
 		}
-		*(uint32_t *)(payload) = htobe32 (relayTag); 
+		htobe32buf (payload, relayTag); 
 		payload += 4; // relay tag 
-		*(uint32_t *)(payload) = htobe32 (i2p::util::GetSecondsSinceEpoch ()); // signed on time
+		htobe32buf (payload, i2p::util::GetSecondsSinceEpoch ()); // signed on time
 		payload += 4;
 		s.Insert (payload - 8, 8); // relayTag and signed on time 
 		s.Sign (i2p::context.GetPrivateKeys (), payload); // DSA signature
@@ -404,12 +404,12 @@ namespace transport
 		*payload = 1; // 1 fragment
 		payload++; // info
 		size_t identLen = i2p::context.GetIdentity ().GetFullLen (); // 387+ bytes
-		*(uint16_t *)(payload) = htobe16 (identLen);
+		htobe16buf (payload, identLen);
 		payload += 2; // cursize
 		i2p::context.GetIdentity ().ToBuffer (payload, identLen);
 		payload += identLen;
 		uint32_t signedOnTime = i2p::util::GetSecondsSinceEpoch ();
-		*(uint32_t *)(payload) = htobe32 (signedOnTime); // signed on time
+		htobe32buf (payload, signedOnTime); // signed on time
 		payload += 4;
 		auto signatureLen = i2p::context.GetIdentity ().GetSignatureLen ();
 		size_t paddingSize = ((payload - buf) + signatureLen)%16;
@@ -476,9 +476,9 @@ namespace transport
 		}
 		*payload = 4;
 		payload++; // size
-		*(uint32_t *)payload = htobe32 (to.address ().to_v4 ().to_ulong ()); // Charlie's IP
+		htobe32buf (payload, to.address ().to_v4 ().to_ulong ()); // Charlie's IP
 		payload += 4; // address	
-		*(uint16_t *)payload = htobe16 (to.port ()); // Charlie's port
+		htobe16buf (payload, to.port ()); // Charlie's port
 		payload += 2; // port
 		// Alice
 		bool isV4 = from.address ().is_v4 (); // Alice's
@@ -496,9 +496,9 @@ namespace transport
 			memcpy (payload, from.address ().to_v6 ().to_bytes ().data (), 16); // Alice's IP V6
 			payload += 16; // address	
 		}
-		*(uint16_t *)payload = htobe16 (from.port ()); // Alice's port
+		htobe16buf (payload, from.port ()); // Alice's port
 		payload += 2; // port
-		*(uint32_t *)payload = htobe32 (nonce);		
+		htobe32buf (payload, nonce);		
 
 		if (m_State == eSessionStateEstablished)
 		{	
@@ -531,9 +531,9 @@ namespace transport
 		uint8_t * payload = buf + sizeof (SSUHeader);
 		*payload = 4;
 		payload++; // size
-		*(uint32_t *)payload = htobe32 (from.address ().to_v4 ().to_ulong ()); // Alice's IP
+		htobe32buf (payload, from.address ().to_v4 ().to_ulong ()); // Alice's IP
 		payload += 4; // address	
-		*(uint16_t *)payload = htobe16 (from.port ()); // Alice's port
+		htobe16buf (payload, from.port ()); // Alice's port
 		payload += 2; // port
 		*payload = 0; // challenge size	
 		uint8_t iv[16];
@@ -612,7 +612,7 @@ namespace transport
 		encryption.Encrypt (encrypted, encryptedLen, encrypted);
 		// assume actual buffer size is 18 (16 + 2) bytes more
 		memcpy (buf + len, iv, 16);
-		*(uint16_t *)(buf + len + 16) = htobe16 (encryptedLen);
+		htobe16buf (buf + len + 16, encryptedLen);
 		i2p::crypto::HMACMD5Digest (encrypted, encryptedLen + 18, macKey, header->mac);
 	}
 
@@ -633,7 +633,7 @@ namespace transport
 		m_SessionKeyEncryption.Encrypt (encrypted, encryptedLen, encrypted);
 		// assume actual buffer size is 18 (16 + 2) bytes more
 		memcpy (buf + len, header->iv, 16);
-		*(uint16_t *)(buf + len + 16) = htobe16 (encryptedLen);
+		htobe16buf (buf + len + 16, encryptedLen);
 		i2p::crypto::HMACMD5Digest (encrypted, encryptedLen + 18, m_MacKey, header->mac);
 	}	
 		
@@ -682,7 +682,7 @@ namespace transport
 		uint16_t encryptedLen = len - (encrypted - buf);
 		// assume actual buffer size is 18 (16 + 2) bytes more
 		memcpy (buf + len, header->iv, 16);
-		*(uint16_t *)(buf + len + 16) = htobe16 (encryptedLen);
+		htobe16buf (buf + len + 16, encryptedLen);
 		uint8_t digest[16];
 		i2p::crypto::HMACMD5Digest (encrypted, encryptedLen + 18, macKey, digest);
 		return !memcmp (header->mac, digest, 16);
@@ -849,9 +849,9 @@ namespace transport
 		uint8_t size = *buf;
 		buf++; // size
 		
-		uint32_t address = (size == 4) ? *(uint32_t *)buf : 0; // use it as is
+		uint32_t address = (size == 4) ? buf32toh(buf) : 0; // use it as is
 		buf += size; // address
-		uint16_t port = *(uint16_t *)buf; // use it as is
+		uint16_t port = buf16toh(buf); // use it as is
 		buf += 2; // port
 		uint8_t * introKey = buf;
 		if (port && !address)
@@ -915,13 +915,13 @@ namespace transport
 		uint8_t buf[80 + 18];
 		uint8_t iv[16];
 		uint8_t * payload = buf + sizeof (SSUHeader);
-		*(uint32_t *)payload = htobe32 (nonce);
+		htobe32buf (payload, nonce);
 		payload += 4; // nonce	
 		if (address)
 		{					
 			*payload = 4;
 			payload++; // size
-			*(uint32_t *)payload = htobe32 (address);
+			htobe32buf (payload, address);
 			payload += 4; // address
 		}
 		else
@@ -929,7 +929,7 @@ namespace transport
 			*payload = 0;
 			payload++; //size
 		}
-		*(uint16_t *)payload = htobe16 (port);
+		htobe16buf (payload, port);
 		payload += 2; // port
 		memcpy (payload, introKey, 32); // intro key
 
diff --git a/Streaming.cpp b/Streaming.cpp
index fa353275..3aa5f835 100644
--- a/Streaming.cpp
+++ b/Streaming.cpp
@@ -256,16 +256,16 @@ namespace stream
 			uint8_t * packet = p->GetBuffer ();
 			// TODO: implement setters
 			size_t size = 0;
-			*(uint32_t *)(packet + size) = htobe32 (m_SendStreamID);
+			htobe32buf (packet + size, m_SendStreamID);
 			size += 4; // sendStreamID
-			*(uint32_t *)(packet + size) = htobe32 (m_RecvStreamID);
+			htobe32buf (packet + size, m_RecvStreamID);
 			size += 4; // receiveStreamID
-			*(uint32_t *)(packet + size) = htobe32 (m_SequenceNumber++);
+			htobe32buf (packet + size, m_SequenceNumber++);
 			size += 4; // sequenceNum
 			if (isNoAck)			
-				*(uint32_t *)(packet + size) = htobe32 (m_LastReceivedSequenceNumber);
+				htobe32buf (packet + size, m_LastReceivedSequenceNumber);
 			else
-				*(uint32_t *)(packet + size) = 0;
+				htobuf32 (packet + size, 0);
 			size += 4; // ack Through
 			packet[size] = 0; 
 			size++; // NACK count
@@ -277,15 +277,15 @@ namespace stream
 				uint16_t flags = PACKET_FLAG_SYNCHRONIZE | PACKET_FLAG_FROM_INCLUDED | 
 					PACKET_FLAG_SIGNATURE_INCLUDED | PACKET_FLAG_MAX_PACKET_SIZE_INCLUDED;
 				if (isNoAck) flags |= PACKET_FLAG_NO_ACK;
-				*(uint16_t *)(packet + size) = htobe16 (flags);
+				htobe16buf (packet + size, flags);
 				size += 2; // flags
 				size_t identityLen = m_LocalDestination.GetOwner ().GetIdentity ().GetFullLen ();
 				size_t signatureLen = m_LocalDestination.GetOwner ().GetIdentity ().GetSignatureLen ();
-				*(uint16_t *)(packet + size) = htobe16 (identityLen + signatureLen + 2); // identity + signature + packet size
+				htobe16buf (packet + size, identityLen + signatureLen + 2); // identity + signature + packet size
 				size += 2; // options size
 				m_LocalDestination.GetOwner ().GetIdentity ().ToBuffer (packet + size, identityLen); 
 				size += identityLen; // from
-				*(uint16_t *)(packet + size) = htobe16 (STREAMING_MTU);
+				htobe16buf (packet + size, STREAMING_MTU);
 				size += 2; // max packet size
 				uint8_t * signature = packet + size; // set it later
 				memset (signature, 0, signatureLen); // zeroes for now
@@ -301,9 +301,9 @@ namespace stream
 			else
 			{
 				// follow on packet
-				*(uint16_t *)(packet + size) = 0;
+				htobuf16 (packet + size, 0);
 				size += 2; // flags
-				*(uint16_t *)(packet + size) = 0; // no options
+				htobuf16 (packet + size, 0); // no options
 				size += 2; // options size
 				size_t sentLen = STREAMING_MTU - size;
 				if (len < sentLen) sentLen = len;		
@@ -338,13 +338,13 @@ namespace stream
 		Packet p;
 		uint8_t * packet = p.GetBuffer ();	
 		size_t size = 0;
-		*(uint32_t *)(packet + size) = htobe32 (m_SendStreamID);
+		htobe32buf (packet + size, m_SendStreamID);
 		size += 4; // sendStreamID
-		*(uint32_t *)(packet + size) = htobe32 (m_RecvStreamID);
+		htobe32buf (packet + size, m_RecvStreamID);
 		size += 4; // receiveStreamID
-		*(uint32_t *)(packet + size) = 0; // this is plain Ack message
+		htobuf32 (packet + size, 0); // this is plain Ack message
 		size += 4; // sequenceNum
-		*(uint32_t *)(packet + size) = htobe32 (lastReceivedSeqn);
+		htobe32buf (packet + size, lastReceivedSeqn);
 		size += 4; // ack Through
 		if (lastReceivedSeqn > m_LastReceivedSequenceNumber) 
 		{	
@@ -357,7 +357,7 @@ namespace stream
 				auto seqn = it->GetSeqn ();
 				for (uint32_t i = nextSeqn; i < seqn; i++)
 				{
-					*(uint32_t *)nacks = htobe32 (i);
+					htobe32buf (nacks, i);
 					nacks += 4;
 					numNacks++;
 				}	
@@ -374,9 +374,9 @@ namespace stream
 			size++; // NACK count		
 		}	
 		size++; // resend delay
-		*(uint16_t *)(packet + size) = 0; // nof flags set
+		htobuf16 (packet + size, 0); // nof flags set
 		size += 2; // flags
-		*(uint16_t *)(packet + size) = 0; // no options
+		htobuf16 (packet + size, 0); // no options
 		size += 2; // options size
 		p.len = size;		
 
@@ -392,21 +392,21 @@ namespace stream
 			Packet * p = new Packet ();
 			uint8_t * packet = p->GetBuffer ();
 			size_t size = 0;
-			*(uint32_t *)(packet + size) = htobe32 (m_SendStreamID);
+			htobe32buf (packet + size, m_SendStreamID);
 			size += 4; // sendStreamID
-			*(uint32_t *)(packet + size) = htobe32 (m_RecvStreamID);
+			htobe32buf (packet + size, m_RecvStreamID);
 			size += 4; // receiveStreamID
-			*(uint32_t *)(packet + size) = htobe32 (m_SequenceNumber++);
+			htobe32buf (packet + size, m_SequenceNumber++);
 			size += 4; // sequenceNum
-			*(uint32_t *)(packet + size) = htobe32 (m_LastReceivedSequenceNumber);
+			htobe32buf (packet + size, m_LastReceivedSequenceNumber);
 			size += 4; // ack Through
 			packet[size] = 0; 
 			size++; // NACK count
 			size++; // resend delay
-			*(uint16_t *)(packet + size) = htobe16 (PACKET_FLAG_CLOSE | PACKET_FLAG_SIGNATURE_INCLUDED);
+			htobe16buf (packet + size, PACKET_FLAG_CLOSE | PACKET_FLAG_SIGNATURE_INCLUDED);
 			size += 2; // flags
 			size_t signatureLen = m_LocalDestination.GetOwner ().GetIdentity ().GetSignatureLen ();
-			*(uint16_t *)(packet + size) = htobe16 (signatureLen); // signature only
+			htobe16buf (packet + size, signatureLen); // signature only
 			size += 2; // options size
 			uint8_t * signature = packet + size;
 			memset (packet + size, 0, signatureLen);
@@ -617,11 +617,11 @@ namespace stream
 		compressor.MessageEnd();
 		int size = compressor.MaxRetrievable ();
 		uint8_t * buf = msg->GetPayload ();
-		*(uint32_t *)buf = htobe32 (size); // length
+		htobe32buf (buf, size); // length
 		buf += 4;
 		compressor.Get (buf, size);
-		*(uint16_t *)(buf + 4) = 0; // source port
-		*(uint16_t *)(buf + 6) = htobe16 (m_Port); // destination port 
+		htobuf16(buf + 4, 0); // source port
+		htobe16buf (buf + 6, m_Port); // destination port 
 		buf[9] = i2p::client::PROTOCOL_TYPE_STREAMING; // streaming protocol
 		msg->len += size + 4; 
 		FillI2NPMessageHeader (msg, eI2NPData);
diff --git a/TransitTunnel.cpp b/TransitTunnel.cpp
index 25b82424..1f755be5 100644
--- a/TransitTunnel.cpp
+++ b/TransitTunnel.cpp
@@ -31,7 +31,7 @@ namespace tunnel
 		
 		LogPrint ("TransitTunnel: ",m_TunnelID,"->", m_NextTunnelID);
 		m_NumTransmittedBytes += tunnelMsg->GetLength ();
-		*(uint32_t *)(tunnelMsg->GetPayload ()) = htobe32 (m_NextTunnelID);
+		htobe32buf (tunnelMsg->GetPayload (), m_NextTunnelID);
 		FillI2NPMessageHeader (tunnelMsg, eI2NPTunnelData);
 		
 		i2p::transport::transports.SendMessage (m_NextIdent, tunnelMsg);	
diff --git a/TunnelGateway.cpp b/TunnelGateway.cpp
index d2f26bd9..3b3980e0 100644
--- a/TunnelGateway.cpp
+++ b/TunnelGateway.cpp
@@ -26,7 +26,7 @@ namespace tunnel
 		{	
 			if (block.deliveryType == eDeliveryTypeTunnel)
 			{
-				*(uint32_t *)(di + diLen) = htobe32 (block.tunnelID);
+				htobe32buf (di + diLen, block.tunnelID);
 				diLen += 4; // tunnelID
 			}
 			
@@ -41,7 +41,7 @@ namespace tunnel
 		if (fullMsgLen <= m_RemainingSize)
 		{
 			// message fits. First and last fragment
-			*(uint16_t *)(di + diLen) = htobe16 (msg->GetLength ());
+			htobe16buf (di + diLen, msg->GetLength ());
 			diLen += 2; // size
 			memcpy (m_CurrentTunnelDataMsg->buf + m_CurrentTunnelDataMsg->len, di, diLen);
 			memcpy (m_CurrentTunnelDataMsg->buf + m_CurrentTunnelDataMsg->len + diLen, msg->GetBuffer (), msg->GetLength ());
@@ -73,9 +73,9 @@ namespace tunnel
 
 				// first fragment
 				di[0] |= 0x08; // fragmented
-				*(uint32_t *)(di + diLen) = msgID;
+				htobuf32 (di + diLen, msgID);
 				diLen += 4; // Message ID
-				*(uint16_t *)(di + diLen) = htobe16 (size);
+				htobe16buf (di + diLen, size);
 				diLen += 2; // size
 				memcpy (m_CurrentTunnelDataMsg->buf + m_CurrentTunnelDataMsg->len, di, diLen);
 				memcpy (m_CurrentTunnelDataMsg->buf + m_CurrentTunnelDataMsg->len + diLen, msg->GetBuffer (), size);
@@ -96,9 +96,9 @@ namespace tunnel
 					{	
 						buf[0] |= 0x01;
 						isLastFragment = true;
-					}	
-					*(uint32_t *)(buf + 1) = msgID; //Message ID
-					*(uint16_t *)(buf + 5) = htobe16 (s); // size
+					}
+					htobuf32 (buf + 1, msgID); //Message ID
+					htobe16buf (buf + 5, s); // size
 					memcpy (buf + 7, msg->GetBuffer () + size, s);
 					m_CurrentTunnelDataMsg->len += s+7;
 					if (isLastFragment)
@@ -147,7 +147,7 @@ namespace tunnel
 		
 		m_CurrentTunnelDataMsg->offset = m_CurrentTunnelDataMsg->len - TUNNEL_DATA_MSG_SIZE - sizeof (I2NPHeader);
 		uint8_t * buf = m_CurrentTunnelDataMsg->GetPayload ();
-		*(uint32_t *)(buf) = htobe32 (m_TunnelID);
+		htobe32buf (buf, m_TunnelID);
 		CryptoPP::RandomNumberGenerator& rnd = i2p::context.GetRandomNumberGenerator ();
 		rnd.GenerateBlock (buf + 4, 16); // original IV	
 		memcpy (payload + size, buf + 4, 16); // copy IV for checksum