diff --git a/libraries/base/common/src/vhdl/common_network_total_header_pkg.vhd b/libraries/base/common/src/vhdl/common_network_total_header_pkg.vhd
index 8212c0edaec24764c83ede03f2fecaaa3fe9605f..868c80e2ca1a21d51ecf6373a53103082029fbb9 100644
--- a/libraries/base/common/src/vhdl/common_network_total_header_pkg.vhd
+++ b/libraries/base/common/src/vhdl/common_network_total_header_pkg.vhd
@@ -43,6 +43,12 @@
 --         6   |    |         |  |
 --         7   |    |         |  |
 --
+-- The word align separates the network total header and the udp payload on a word boundary. This allows the network 
+-- total header to be handled as a t_network_total_header_<word width>_arr. It is also useful for the data path
+-- application that can handle the UDP payload on word boundaries. For output to the MAC the word align can be removed
+-- using dp_pad_remove. For input from the MAC the word align can be inserted using dp_pad_insert.
+--
+
 LIBRARY IEEE;
 USE IEEE.std_logic_1164.ALL;
 USE IEEE.numeric_std.ALL;
@@ -88,6 +94,7 @@ PACKAGE common_network_total_header_pkg IS
   TYPE t_network_total_header_64b_arr IS ARRAY(0 TO c_network_total_header_64b_nof_words-1) OF STD_LOGIC_VECTOR(c_64-1 DOWNTO 0);
   
   -- Word indices in the total header array to know when the field in the mapped record is valid
+  -- . 32b
   CONSTANT c_network_total_header_32b_eth_lo_wi              : NATURAL := 0;  -- first word index
   CONSTANT c_network_total_header_32b_eth_dst_mac_wi         : NATURAL := 1;
   CONSTANT c_network_total_header_32b_eth_src_mac_wi         : NATURAL := 3;
@@ -141,30 +148,103 @@ PACKAGE common_network_total_header_pkg IS
   CONSTANT c_network_total_header_32b_udp_hi_wi              : NATURAL := 10;  -- last word index
   CONSTANT c_network_total_header_32b_udp_nof_words          : NATURAL := c_network_total_header_32b_udp_hi_wi - c_network_total_header_32b_udp_lo_wi + 1;
 
+  -- . 64b
+  CONSTANT c_network_total_header_64b_eth_lo_wi              : NATURAL := 0;  -- first word index
+  CONSTANT c_network_total_header_64b_eth_dst_mac_wi         : NATURAL := 1;
+  CONSTANT c_network_total_header_64b_eth_src_mac_wi         : NATURAL := 2;
+  CONSTANT c_network_total_header_64b_eth_type_wi            : NATURAL := 2;
+  CONSTANT c_network_total_header_64b_eth_hi_wi              : NATURAL := 2;  -- last word index
+  CONSTANT c_network_total_header_64b_eth_nof_words          : NATURAL := c_network_total_header_64b_eth_hi_wi - c_network_total_header_64b_eth_lo_wi + 1;
+  
+  CONSTANT c_network_total_header_64b_ip_lo_wi               : NATURAL := 2;  -- first word index
+  CONSTANT c_network_total_header_64b_ip_version_wi          : NATURAL := 2;
+  CONSTANT c_network_total_header_64b_ip_header_length_wi    : NATURAL := 2;
+  CONSTANT c_network_total_header_64b_ip_services_wi         : NATURAL := 2;
+  CONSTANT c_network_total_header_64b_ip_total_length_wi     : NATURAL := 2;
+  CONSTANT c_network_total_header_64b_ip_identification_wi   : NATURAL := 3;
+  CONSTANT c_network_total_header_64b_ip_flags_wi            : NATURAL := 3;
+  CONSTANT c_network_total_header_64b_ip_fragment_offset_wi  : NATURAL := 3;
+  CONSTANT c_network_total_header_64b_ip_time_to_live_wi     : NATURAL := 3;
+  CONSTANT c_network_total_header_64b_ip_protocol_wi         : NATURAL := 3;
+  CONSTANT c_network_total_header_64b_ip_header_checksum_wi  : NATURAL := 3;
+  CONSTANT c_network_total_header_64b_ip_src_ip_addr_wi      : NATURAL := 4;
+  CONSTANT c_network_total_header_64b_ip_dst_ip_addr_wi      : NATURAL := 4;
+  CONSTANT c_network_total_header_64b_ip_hi_wi               : NATURAL := 4;  -- last word index
+  CONSTANT c_network_total_header_64b_ip_nof_words           : NATURAL := c_network_total_header_64b_ip_hi_wi - c_network_total_header_64b_ip_lo_wi + 1;
+
+  CONSTANT c_network_total_header_64b_arp_lo_wi              : NATURAL := 2;  -- first word index
+  CONSTANT c_network_total_header_64b_arp_htype_wi           : NATURAL := 2;
+  CONSTANT c_network_total_header_64b_arp_ptype_wi           : NATURAL := 2;
+  CONSTANT c_network_total_header_64b_arp_hlen_wi            : NATURAL := 3;
+  CONSTANT c_network_total_header_64b_arp_plen_wi            : NATURAL := 3;
+  CONSTANT c_network_total_header_64b_arp_oper_wi            : NATURAL := 3;
+  CONSTANT c_network_total_header_64b_arp_sha_wi             : NATURAL := 4;
+  CONSTANT c_network_total_header_64b_arp_spa_wi             : NATURAL := 4;
+  CONSTANT c_network_total_header_64b_arp_tha_wi             : NATURAL := 5;
+  CONSTANT c_network_total_header_64b_arp_tpa_wi             : NATURAL := 5;
+  CONSTANT c_network_total_header_64b_arp_hi_wi              : NATURAL := 5;  -- last word index
+  CONSTANT c_network_total_header_64b_arp_nof_words          : NATURAL := c_network_total_header_64b_arp_hi_wi - c_network_total_header_64b_arp_lo_wi + 1;
+
+  CONSTANT c_network_total_header_64b_icmp_lo_wi             : NATURAL := 5;  -- first word index                                            
+  CONSTANT c_network_total_header_64b_icmp_msg_type_wi       : NATURAL := 5;                                                                  
+  CONSTANT c_network_total_header_64b_icmp_code_wi           : NATURAL := 5;                                                                  
+  CONSTANT c_network_total_header_64b_icmp_checksum_wi       : NATURAL := 5;                                                                  
+  CONSTANT c_network_total_header_64b_icmp_id_wi             : NATURAL := 5;                                                                 
+  CONSTANT c_network_total_header_64b_icmp_sequence_wi       : NATURAL := 5;                                                                 
+  CONSTANT c_network_total_header_64b_icmp_hi_wi             : NATURAL := 5;  -- last word index                                             
+  CONSTANT c_network_total_header_64b_icmp_nof_words         : NATURAL := c_network_total_header_64b_icmp_hi_wi - c_network_total_header_64b_icmp_lo_wi + 1;
+  
+  CONSTANT c_network_total_header_64b_udp_lo_wi              : NATURAL := 5;  -- first word index
+  CONSTANT c_network_total_header_64b_udp_src_port_wi        : NATURAL := 5;
+  CONSTANT c_network_total_header_64b_udp_dst_port_wi        : NATURAL := 5;
+  CONSTANT c_network_total_header_64b_udp_total_length_wi    : NATURAL := 5;
+  CONSTANT c_network_total_header_64b_udp_checksum_wi        : NATURAL := 5;
+  CONSTANT c_network_total_header_64b_udp_hi_wi              : NATURAL := 5;  -- last word index
+  CONSTANT c_network_total_header_64b_udp_nof_words          : NATURAL := c_network_total_header_64b_udp_hi_wi - c_network_total_header_64b_udp_lo_wi + 1;
+  
   -----------------------------------------------------------------------------
   -- Functions to map between header record fields and header words array
   -----------------------------------------------------------------------------
   
   -- Combinatorial map of the total header array on to a network header record (type casting an array to a record is not possible, so therefore we need these functions)
   FUNCTION func_network_total_header_extract_eth( hdr_arr : t_network_total_header_32b_arr) RETURN t_network_eth_header;
+  FUNCTION func_network_total_header_extract_eth( hdr_arr : t_network_total_header_64b_arr) RETURN t_network_eth_header;
   FUNCTION func_network_total_header_extract_ip(  hdr_arr : t_network_total_header_32b_arr) RETURN t_network_ip_header;
+  FUNCTION func_network_total_header_extract_ip(  hdr_arr : t_network_total_header_64b_arr) RETURN t_network_ip_header;
   FUNCTION func_network_total_header_extract_arp( hdr_arr : t_network_total_header_32b_arr) RETURN t_network_arp_packet;
+  FUNCTION func_network_total_header_extract_arp( hdr_arr : t_network_total_header_64b_arr) RETURN t_network_arp_packet;
   FUNCTION func_network_total_header_extract_icmp(hdr_arr : t_network_total_header_32b_arr) RETURN t_network_icmp_header;
+  FUNCTION func_network_total_header_extract_icmp(hdr_arr : t_network_total_header_64b_arr) RETURN t_network_icmp_header;
   FUNCTION func_network_total_header_extract_udp( hdr_arr : t_network_total_header_32b_arr) RETURN t_network_udp_header;
+  FUNCTION func_network_total_header_extract_udp( hdr_arr : t_network_total_header_64b_arr) RETURN t_network_udp_header;
   
   -- Construct the total header array from the individual header records
+  FUNCTION func_network_total_header_construct_eth( eth : t_network_eth_header)                                                          RETURN t_network_total_header_32b_arr;  -- sets unused words to zero
+  FUNCTION func_network_total_header_construct_eth( eth : t_network_eth_header)                                                          RETURN t_network_total_header_64b_arr;  -- sets unused words to zero
   FUNCTION func_network_total_header_construct_arp( eth : t_network_eth_header; arp : t_network_arp_packet)                              RETURN t_network_total_header_32b_arr;
+  FUNCTION func_network_total_header_construct_arp( eth : t_network_eth_header; arp : t_network_arp_packet)                              RETURN t_network_total_header_64b_arr;
+  FUNCTION func_network_total_header_construct_ip(  eth : t_network_eth_header; ip  : t_network_ip_header)                               RETURN t_network_total_header_32b_arr;  -- sets unused words to zero
+  FUNCTION func_network_total_header_construct_ip(  eth : t_network_eth_header; ip  : t_network_ip_header)                               RETURN t_network_total_header_64b_arr;  -- sets unused words to zero
   FUNCTION func_network_total_header_construct_icmp(eth : t_network_eth_header; ip  : t_network_ip_header; icmp : t_network_icmp_header) RETURN t_network_total_header_32b_arr;
+  FUNCTION func_network_total_header_construct_icmp(eth : t_network_eth_header; ip  : t_network_ip_header; icmp : t_network_icmp_header) RETURN t_network_total_header_64b_arr;
   FUNCTION func_network_total_header_construct_udp( eth : t_network_eth_header; ip  : t_network_ip_header; udp  : t_network_udp_header)  RETURN t_network_total_header_32b_arr;
+  FUNCTION func_network_total_header_construct_udp( eth : t_network_eth_header; ip  : t_network_ip_header; udp  : t_network_udp_header)  RETURN t_network_total_header_64b_arr;
   
   -- Construct the response total header array for a total header array
   FUNCTION func_network_total_header_response_eth( eth_arr  : t_network_total_header_32b_arr; mac_addr : STD_LOGIC_VECTOR(c_network_eth_mac_addr_w-1 DOWNTO 0)) RETURN t_network_total_header_32b_arr;
+  FUNCTION func_network_total_header_response_eth( eth_arr  : t_network_total_header_64b_arr; mac_addr : STD_LOGIC_VECTOR(c_network_eth_mac_addr_w-1 DOWNTO 0)) RETURN t_network_total_header_64b_arr;
   FUNCTION func_network_total_header_response_arp( arp_arr  : t_network_total_header_32b_arr; mac_addr : STD_LOGIC_VECTOR(c_network_eth_mac_addr_w-1 DOWNTO 0);
                                                                                               ip_addr  : STD_LOGIC_VECTOR(c_network_ip_addr_w-1 DOWNTO 0))
                                                                                               RETURN t_network_total_header_32b_arr;
+  FUNCTION func_network_total_header_response_arp( arp_arr  : t_network_total_header_64b_arr; mac_addr : STD_LOGIC_VECTOR(c_network_eth_mac_addr_w-1 DOWNTO 0);
+                                                                                              ip_addr  : STD_LOGIC_VECTOR(c_network_ip_addr_w-1 DOWNTO 0))
+                                                                                              RETURN t_network_total_header_64b_arr;
   FUNCTION func_network_total_header_response_ip(  ip_arr   : t_network_total_header_32b_arr; mac_addr : STD_LOGIC_VECTOR(c_network_eth_mac_addr_w-1 DOWNTO 0)) RETURN t_network_total_header_32b_arr;
+  FUNCTION func_network_total_header_response_ip(  ip_arr   : t_network_total_header_64b_arr; mac_addr : STD_LOGIC_VECTOR(c_network_eth_mac_addr_w-1 DOWNTO 0)) RETURN t_network_total_header_64b_arr;
   FUNCTION func_network_total_header_response_icmp(icmp_arr : t_network_total_header_32b_arr; mac_addr : STD_LOGIC_VECTOR(c_network_eth_mac_addr_w-1 DOWNTO 0)) RETURN t_network_total_header_32b_arr;
+  FUNCTION func_network_total_header_response_icmp(icmp_arr : t_network_total_header_64b_arr; mac_addr : STD_LOGIC_VECTOR(c_network_eth_mac_addr_w-1 DOWNTO 0)) RETURN t_network_total_header_64b_arr;
   FUNCTION func_network_total_header_response_udp( udp_arr  : t_network_total_header_32b_arr; mac_addr : STD_LOGIC_VECTOR(c_network_eth_mac_addr_w-1 DOWNTO 0)) RETURN t_network_total_header_32b_arr;
+  FUNCTION func_network_total_header_response_udp( udp_arr  : t_network_total_header_64b_arr; mac_addr : STD_LOGIC_VECTOR(c_network_eth_mac_addr_w-1 DOWNTO 0)) RETURN t_network_total_header_64b_arr;
   
 END common_network_total_header_pkg;
 
@@ -186,6 +266,18 @@ PACKAGE BODY common_network_total_header_pkg IS
     RETURN v_hdr;
   END;
   
+  FUNCTION func_network_total_header_extract_eth(hdr_arr : t_network_total_header_64b_arr) RETURN t_network_eth_header IS
+    VARIABLE v_hdr : t_network_eth_header;
+  BEGIN
+    --                             hdr_arr(0)(63 DOWNTO 16)  -- ignore word align field
+    v_hdr.dst_mac(47 DOWNTO 32) := hdr_arr(0)(15 DOWNTO  0);
+    v_hdr.dst_mac(31 DOWNTO  0) := hdr_arr(1)(63 DOWNTO 32);
+    v_hdr.src_mac(47 DOWNTO 16) := hdr_arr(1)(31 DOWNTO  0);
+    v_hdr.src_mac(15 DOWNTO  0) := hdr_arr(2)(63 DOWNTO 48);
+    v_hdr.eth_type              := hdr_arr(2)(47 DOWNTO 32);
+    RETURN v_hdr;
+  END;
+  
   FUNCTION func_network_total_header_extract_ip(hdr_arr : t_network_total_header_32b_arr) RETURN t_network_ip_header IS
     VARIABLE v_hdr : t_network_ip_header;
   BEGIN
@@ -204,6 +296,24 @@ PACKAGE BODY common_network_total_header_pkg IS
     RETURN v_hdr;
   END;
   
+  FUNCTION func_network_total_header_extract_ip(hdr_arr : t_network_total_header_64b_arr) RETURN t_network_ip_header IS
+    VARIABLE v_hdr : t_network_ip_header;
+  BEGIN
+    v_hdr.version            := hdr_arr(2)(31 DOWNTO 28);
+    v_hdr.header_length      := hdr_arr(2)(27 DOWNTO 24);
+    v_hdr.services           := hdr_arr(2)(23 DOWNTO 16);
+    v_hdr.total_length       := hdr_arr(2)(15 DOWNTO  0);
+    v_hdr.identification     := hdr_arr(3)(63 DOWNTO 48);
+    v_hdr.flags              := hdr_arr(3)(47 DOWNTO 45);
+    v_hdr.fragment_offset    := hdr_arr(3)(44 DOWNTO 32);
+    v_hdr.time_to_live       := hdr_arr(3)(31 DOWNTO 24);
+    v_hdr.protocol           := hdr_arr(3)(23 DOWNTO 16);
+    v_hdr.header_checksum    := hdr_arr(3)(15 DOWNTO  0);
+    v_hdr.src_ip_addr        := hdr_arr(4)(63 DOWNTO 32);
+    v_hdr.dst_ip_addr        := hdr_arr(4)(31 DOWNTO  0);
+    RETURN v_hdr;
+  END;
+  
   FUNCTION func_network_total_header_extract_arp(hdr_arr : t_network_total_header_32b_arr) RETURN t_network_arp_packet IS
     VARIABLE v_arp : t_network_arp_packet;
   BEGIN
@@ -222,6 +332,24 @@ PACKAGE BODY common_network_total_header_pkg IS
     RETURN v_arp;
   END;
   
+  FUNCTION func_network_total_header_extract_arp(hdr_arr : t_network_total_header_64b_arr) RETURN t_network_arp_packet IS
+    VARIABLE v_arp : t_network_arp_packet;
+  BEGIN
+    v_arp.htype              := hdr_arr(2)(31 DOWNTO 16);
+    v_arp.ptype              := hdr_arr(2)(15 DOWNTO  0);
+    v_arp.hlen               := hdr_arr(3)(63 DOWNTO 56);
+    v_arp.plen               := hdr_arr(3)(55 DOWNTO 48);
+    v_arp.oper               := hdr_arr(3)(47 DOWNTO 32);
+    v_arp.sha(47 DOWNTO 16)  := hdr_arr(3)(31 DOWNTO  0);
+    v_arp.sha(15 DOWNTO  0)  := hdr_arr(4)(63 DOWNTO 48);
+    v_arp.spa(31 DOWNTO 16)  := hdr_arr(4)(47 DOWNTO 32);
+    v_arp.spa(15 DOWNTO  0)  := hdr_arr(4)(31 DOWNTO 16);
+    v_arp.tha(47 DOWNTO 32)  := hdr_arr(4)(15 DOWNTO  0);
+    v_arp.tha(31 DOWNTO  0)  := hdr_arr(5)(63 DOWNTO 32);
+    v_arp.tpa                := hdr_arr(5)(31 DOWNTO  0);
+    RETURN v_arp;
+  END;
+  
   FUNCTION func_network_total_header_extract_icmp(hdr_arr : t_network_total_header_32b_arr) RETURN t_network_icmp_header IS
     VARIABLE v_hdr : t_network_icmp_header;
   BEGIN
@@ -233,6 +361,17 @@ PACKAGE BODY common_network_total_header_pkg IS
     RETURN v_hdr;
   END;
   
+  FUNCTION func_network_total_header_extract_icmp(hdr_arr : t_network_total_header_64b_arr) RETURN t_network_icmp_header IS
+    VARIABLE v_hdr : t_network_icmp_header;
+  BEGIN
+    v_hdr.msg_type  := hdr_arr(5)(63 DOWNTO 56);
+    v_hdr.code      := hdr_arr(5)(55 DOWNTO 48);
+    v_hdr.checksum  := hdr_arr(5)(47 DOWNTO 32);
+    v_hdr.id        := hdr_arr(5)(31 DOWNTO 16);
+    v_hdr.sequence  := hdr_arr(5)(15 DOWNTO  0);
+    RETURN v_hdr;
+  END;
+  
   FUNCTION func_network_total_header_extract_udp(hdr_arr : t_network_total_header_32b_arr) RETURN t_network_udp_header IS
     VARIABLE v_hdr : t_network_udp_header;
   BEGIN
@@ -243,9 +382,19 @@ PACKAGE BODY common_network_total_header_pkg IS
     RETURN v_hdr;
   END;
   
+  FUNCTION func_network_total_header_extract_udp(hdr_arr : t_network_total_header_64b_arr) RETURN t_network_udp_header IS
+    VARIABLE v_hdr : t_network_udp_header;
+  BEGIN
+    v_hdr.src_port            := hdr_arr(5)(63 DOWNTO 48);
+    v_hdr.dst_port            := hdr_arr(5)(47 DOWNTO 32);
+    v_hdr.total_length        := hdr_arr(5)(31 DOWNTO 16);
+    v_hdr.checksum            := hdr_arr(5)(15 DOWNTO  0);
+    RETURN v_hdr;
+  END;
+  
   -- Construct the total header array from the individual header records
-  FUNCTION func_network_total_header_construct_arp(eth : t_network_eth_header; arp : t_network_arp_packet) RETURN t_network_total_header_32b_arr IS
-    VARIABLE v_total : t_network_total_header_32b_arr;
+  FUNCTION func_network_total_header_construct_eth( eth : t_network_eth_header) RETURN t_network_total_header_32b_arr IS
+    VARIABLE v_total : t_network_total_header_32b_arr := (OTHERS=>(OTHERS=>'0'));
   BEGIN
     v_total(0)(31 DOWNTO 16) := (OTHERS=>'0');  -- force word align to zero
     v_total(0)(15 DOWNTO  0) := eth.dst_mac(47 DOWNTO 32);
@@ -253,7 +402,26 @@ PACKAGE BODY common_network_total_header_pkg IS
     v_total(2)               := eth.src_mac(47 DOWNTO 16);
     v_total(3)(31 DOWNTO 16) := eth.src_mac(15 DOWNTO  0);
     v_total(3)(15 DOWNTO  0) := eth.eth_type;
+    RETURN v_total;
+  END;
   
+  FUNCTION func_network_total_header_construct_eth( eth : t_network_eth_header) RETURN t_network_total_header_64b_arr IS
+    VARIABLE v_total : t_network_total_header_64b_arr := (OTHERS=>(OTHERS=>'0'));
+  BEGIN
+    v_total(0)(63 DOWNTO 16) := (OTHERS=>'0');  -- force word align to zero
+    v_total(0)(15 DOWNTO  0) := eth.dst_mac(47 DOWNTO 32);
+    v_total(1)(63 DOWNTO 32) := eth.dst_mac(31 DOWNTO  0);
+    v_total(1)(31 DOWNTO  0) := eth.src_mac(47 DOWNTO 16);
+    v_total(2)(63 DOWNTO 48) := eth.src_mac(15 DOWNTO  0);
+    v_total(2)(47 DOWNTO 32) := eth.eth_type;
+    RETURN v_total;
+  END;
+  
+  FUNCTION func_network_total_header_construct_arp(eth : t_network_eth_header; arp : t_network_arp_packet) RETURN t_network_total_header_32b_arr IS
+    VARIABLE v_total : t_network_total_header_32b_arr;
+  BEGIN
+    v_total := func_network_total_header_construct_eth(eth);
+    
     v_total(4)(31 DOWNTO 16) := arp.htype;
     v_total(4)(15 DOWNTO  0) := arp.ptype;
     v_total(5)(31 DOWNTO 24) := arp.hlen;
@@ -269,15 +437,29 @@ PACKAGE BODY common_network_total_header_pkg IS
     RETURN v_total;
   END;
   
-  FUNCTION func_network_total_header_construct_icmp(eth : t_network_eth_header; ip : t_network_ip_header; icmp : t_network_icmp_header) RETURN t_network_total_header_32b_arr IS
-    VARIABLE v_total : t_network_total_header_32b_arr;
+  FUNCTION func_network_total_header_construct_arp(eth : t_network_eth_header; arp : t_network_arp_packet) RETURN t_network_total_header_64b_arr IS
+    VARIABLE v_total : t_network_total_header_64b_arr;
   BEGIN
-    v_total(0)(31 DOWNTO 16) := (OTHERS=>'0');  -- force word align to zero
-    v_total(0)(15 DOWNTO  0) := eth.dst_mac(47 DOWNTO 32);
-    v_total(1)               := eth.dst_mac(31 DOWNTO  0);
-    v_total(2)               := eth.src_mac(47 DOWNTO 16);
-    v_total(3)(31 DOWNTO 16) := eth.src_mac(15 DOWNTO  0);
-    v_total(3)(15 DOWNTO  0) := eth.eth_type;
+    v_total := func_network_total_header_construct_eth(eth);
+    
+    v_total(2)(31 DOWNTO 16) := arp.htype;
+    v_total(2)(15 DOWNTO  0) := arp.ptype;
+    v_total(3)(63 DOWNTO 56) := arp.hlen;
+    v_total(3)(55 DOWNTO 48) := arp.plen;
+    v_total(3)(47 DOWNTO 32) := arp.oper;
+    v_total(3)(31 DOWNTO  0) := arp.sha(47 DOWNTO 16);
+    v_total(4)(63 DOWNTO 48) := arp.sha(15 DOWNTO  0);
+    v_total(4)(47 DOWNTO 16) := arp.spa(31 DOWNTO  0);
+    v_total(4)(15 DOWNTO  0) := arp.tha(47 DOWNTO 32);
+    v_total(5)(63 DOWNTO 32) := arp.tha(31 DOWNTO  0);
+    v_total(5)(31 DOWNTO  0) := arp.tpa;
+    RETURN v_total;
+  END;
+  
+  FUNCTION func_network_total_header_construct_ip(eth : t_network_eth_header; ip : t_network_ip_header) RETURN t_network_total_header_32b_arr IS
+    VARIABLE v_total : t_network_total_header_32b_arr := (OTHERS=>(OTHERS=>'0'));
+  BEGIN
+    v_total := func_network_total_header_construct_eth(eth);
     
     v_total(4)(31 DOWNTO 28) := ip.version;
     v_total(4)(27 DOWNTO 24) := ip.header_length;
@@ -290,7 +472,34 @@ PACKAGE BODY common_network_total_header_pkg IS
     v_total(6)(23 DOWNTO 16) := ip.protocol;
     v_total(6)(15 DOWNTO  0) := ip.header_checksum;
     v_total(7)               := ip.src_ip_addr;
-    v_total(8)               := ip.dst_ip_addr;
+    v_total(8)               := ip.dst_ip_addr;    
+    RETURN v_total;
+  END;
+  
+  FUNCTION func_network_total_header_construct_ip(eth : t_network_eth_header; ip : t_network_ip_header) RETURN t_network_total_header_64b_arr IS
+    VARIABLE v_total : t_network_total_header_64b_arr := (OTHERS=>(OTHERS=>'0'));
+  BEGIN
+    v_total := func_network_total_header_construct_eth(eth);
+    
+    v_total(2)(31 DOWNTO 28) := ip.version;
+    v_total(2)(27 DOWNTO 24) := ip.header_length;
+    v_total(2)(23 DOWNTO 16) := ip.services;  
+    v_total(2)(15 DOWNTO  0) := ip.total_length;
+    v_total(3)(63 DOWNTO 48) := ip.identification;
+    v_total(3)(47 DOWNTO 45) := ip.flags;
+    v_total(3)(44 DOWNTO 32) := ip.fragment_offset;
+    v_total(3)(31 DOWNTO 24) := ip.time_to_live;
+    v_total(3)(23 DOWNTO 16) := ip.protocol;
+    v_total(3)(15 DOWNTO  0) := ip.header_checksum;
+    v_total(4)(63 DOWNTO 32) := ip.src_ip_addr;
+    v_total(4)(31 DOWNTO  0) := ip.dst_ip_addr;
+    RETURN v_total;
+  END;
+  
+  FUNCTION func_network_total_header_construct_icmp(eth : t_network_eth_header; ip : t_network_ip_header; icmp : t_network_icmp_header) RETURN t_network_total_header_32b_arr IS
+    VARIABLE v_total : t_network_total_header_32b_arr;
+  BEGIN
+    v_total := func_network_total_header_construct_ip(eth, ip);
     
     v_total(9)(31 DOWNTO 24)  := icmp.msg_type;
     v_total(9)(23 DOWNTO 16)  := icmp.code;
@@ -300,28 +509,23 @@ PACKAGE BODY common_network_total_header_pkg IS
     RETURN v_total;
   END;
   
+  FUNCTION func_network_total_header_construct_icmp(eth : t_network_eth_header; ip : t_network_ip_header; icmp : t_network_icmp_header) RETURN t_network_total_header_64b_arr IS
+    VARIABLE v_total : t_network_total_header_64b_arr;
+  BEGIN
+    v_total := func_network_total_header_construct_ip(eth, ip);
+    
+    v_total(5)(63 DOWNTO 56) := icmp.msg_type;
+    v_total(5)(55 DOWNTO 48) := icmp.code;
+    v_total(5)(47 DOWNTO 32) := icmp.checksum;
+    v_total(5)(31 DOWNTO 16) := icmp.id;
+    v_total(5)(15 DOWNTO  0) := icmp.sequence;
+    RETURN v_total;
+  END;
+  
   FUNCTION func_network_total_header_construct_udp( eth : t_network_eth_header; ip : t_network_ip_header; udp : t_network_udp_header) RETURN t_network_total_header_32b_arr IS
     VARIABLE v_total : t_network_total_header_32b_arr;
   BEGIN
-    v_total(0)(31 DOWNTO 16) := (OTHERS=>'0');  -- force word align to zero
-    v_total(0)(15 DOWNTO  0) := eth.dst_mac(47 DOWNTO 32);
-    v_total(1)               := eth.dst_mac(31 DOWNTO  0);
-    v_total(2)               := eth.src_mac(47 DOWNTO 16);
-    v_total(3)(31 DOWNTO 16) := eth.src_mac(15 DOWNTO  0);
-    v_total(3)(15 DOWNTO  0) := eth.eth_type;
-    
-    v_total(4)(31 DOWNTO 28) := ip.version;
-    v_total(4)(27 DOWNTO 24) := ip.header_length;
-    v_total(4)(23 DOWNTO 16) := ip.services;  
-    v_total(4)(15 DOWNTO  0) := ip.total_length;
-    v_total(5)(31 DOWNTO 16) := ip.identification;
-    v_total(5)(15 DOWNTO 13) := ip.flags;
-    v_total(5)(12 DOWNTO  0) := ip.fragment_offset;
-    v_total(6)(31 DOWNTO 24) := ip.time_to_live;
-    v_total(6)(23 DOWNTO 16) := ip.protocol;
-    v_total(6)(15 DOWNTO  0) := ip.header_checksum;
-    v_total(7)               := ip.src_ip_addr;
-    v_total(8)               := ip.dst_ip_addr;
+    v_total := func_network_total_header_construct_ip(eth, ip);
     
     v_total(9)(31 DOWNTO 16)  := udp.src_port;
     v_total(9)(15 DOWNTO  0)  := udp.dst_port;
@@ -330,6 +534,18 @@ PACKAGE BODY common_network_total_header_pkg IS
     RETURN v_total;
   END;
   
+  FUNCTION func_network_total_header_construct_udp( eth : t_network_eth_header; ip : t_network_ip_header; udp : t_network_udp_header) RETURN t_network_total_header_64b_arr IS
+    VARIABLE v_total : t_network_total_header_64b_arr;
+  BEGIN
+    v_total := func_network_total_header_construct_ip(eth, ip);
+    
+    v_total(5)(63 DOWNTO 48) := udp.src_port;
+    v_total(5)(47 DOWNTO 32) := udp.dst_port;
+    v_total(5)(31 DOWNTO 16) := udp.total_length;
+    v_total(5)(15 DOWNTO  0) := udp.checksum;
+    RETURN v_total;
+  END;
+  
   -- Construct the response headers
   FUNCTION func_network_total_header_response_eth(eth_arr  : t_network_total_header_32b_arr;
                                                   mac_addr : STD_LOGIC_VECTOR(c_network_eth_mac_addr_w-1 DOWNTO 0)) RETURN t_network_total_header_32b_arr IS
@@ -347,6 +563,22 @@ PACKAGE BODY common_network_total_header_pkg IS
     RETURN v_response;
   END;
   
+  FUNCTION func_network_total_header_response_eth(eth_arr  : t_network_total_header_64b_arr;
+                                                  mac_addr : STD_LOGIC_VECTOR(c_network_eth_mac_addr_w-1 DOWNTO 0)) RETURN t_network_total_header_64b_arr IS
+    VARIABLE v_response : t_network_total_header_64b_arr;
+  BEGIN
+    -- Default
+    v_response := eth_arr;
+    -- ETH
+    -- . use input src mac for dst mac
+    v_response(0)(15 DOWNTO  0) := eth_arr(1)(31 DOWNTO 16);
+    v_response(1)(63 DOWNTO 32) := eth_arr(1)(15 DOWNTO  0) & eth_arr(2)(63 DOWNTO 48);
+    -- . force eth src mac to this node mac address (because the input dst_mac can be via eth broadcast mac)
+    v_response(1)(31 DOWNTO  0) := mac_addr(47 DOWNTO 16);
+    v_response(2)(63 DOWNTO 48) := mac_addr(15 DOWNTO  0);
+    RETURN v_response;
+  END;
+  
   FUNCTION func_network_total_header_response_arp(arp_arr  : t_network_total_header_32b_arr;
                                                   mac_addr : STD_LOGIC_VECTOR(c_network_eth_mac_addr_w-1 DOWNTO 0);
                                                   ip_addr  : STD_LOGIC_VECTOR(c_network_ip_addr_w-1 DOWNTO 0)) RETURN t_network_total_header_32b_arr IS
@@ -371,6 +603,29 @@ PACKAGE BODY common_network_total_header_pkg IS
     RETURN v_response;
   END;
   
+  FUNCTION func_network_total_header_response_arp(arp_arr  : t_network_total_header_64b_arr;
+                                                  mac_addr : STD_LOGIC_VECTOR(c_network_eth_mac_addr_w-1 DOWNTO 0);
+                                                  ip_addr  : STD_LOGIC_VECTOR(c_network_ip_addr_w-1 DOWNTO 0)) RETURN t_network_total_header_64b_arr IS
+    VARIABLE v_response : t_network_total_header_64b_arr;
+  BEGIN
+    -- ETH
+    v_response := func_network_total_header_response_eth(arp_arr, mac_addr);
+    -- ARP
+    -- . force operation arp reply
+    v_response(3)(47 DOWNTO 32) := TO_UVEC(c_network_arp_oper_reply, 16);
+    -- . force sha to this node mac address
+    v_response(3)(31 DOWNTO  0) := mac_addr(47 DOWNTO 16);
+    v_response(4)(63 DOWNTO 48) := mac_addr(15 DOWNTO  0);
+    -- . force spa to this node ip address
+    v_response(4)(47 DOWNTO 16) := ip_addr(31 DOWNTO  0);
+    -- . use input sha for tha
+    v_response(4)(15 DOWNTO  0) := arp_arr(3)(31 DOWNTO 16);
+    v_response(5)(63 DOWNTO 32) := arp_arr(3)(15 DOWNTO  0) & arp_arr(4)(63 DOWNTO 48);
+    -- . use input spa for tpa
+    v_response(5)(31 DOWNTO  0) := arp_arr(4)(47 DOWNTO 16);
+    RETURN v_response;
+  END;
+  
   FUNCTION func_network_total_header_response_ip(ip_arr   : t_network_total_header_32b_arr;
                                                  mac_addr : STD_LOGIC_VECTOR(c_network_eth_mac_addr_w-1 DOWNTO 0)) RETURN t_network_total_header_32b_arr IS
     VARIABLE v_response : t_network_total_header_32b_arr;
@@ -386,6 +641,21 @@ PACKAGE BODY common_network_total_header_pkg IS
     RETURN v_response;
   END;
   
+  FUNCTION func_network_total_header_response_ip(ip_arr   : t_network_total_header_64b_arr;
+                                                 mac_addr : STD_LOGIC_VECTOR(c_network_eth_mac_addr_w-1 DOWNTO 0)) RETURN t_network_total_header_64b_arr IS
+    VARIABLE v_response : t_network_total_header_64b_arr;
+  BEGIN
+    -- ETH
+    v_response := func_network_total_header_response_eth(ip_arr, mac_addr);
+    -- IP
+    -- . force ip header checksum to 0
+    v_response(3)(15 DOWNTO  0) := TO_UVEC(0, 16);
+    -- . swap ip dst_addr and ip src_addr
+    v_response(4)(63 DOWNTO 32) := ip_arr(4)(31 DOWNTO  0);
+    v_response(4)(31 DOWNTO  0) := ip_arr(4)(63 DOWNTO 32);
+    RETURN v_response;
+  END;
+  
   FUNCTION func_network_total_header_response_icmp(icmp_arr : t_network_total_header_32b_arr;
                                                    mac_addr : STD_LOGIC_VECTOR(c_network_eth_mac_addr_w-1 DOWNTO 0)) RETURN t_network_total_header_32b_arr IS
     VARIABLE v_response : t_network_total_header_32b_arr;
@@ -399,6 +669,19 @@ PACKAGE BODY common_network_total_header_pkg IS
     RETURN v_response;
   END;
   
+  FUNCTION func_network_total_header_response_icmp(icmp_arr : t_network_total_header_64b_arr;
+                                                   mac_addr : STD_LOGIC_VECTOR(c_network_eth_mac_addr_w-1 DOWNTO 0)) RETURN t_network_total_header_64b_arr IS
+    VARIABLE v_response : t_network_total_header_64b_arr;
+  BEGIN
+    -- ETH, IP
+    v_response := func_network_total_header_response_ip(icmp_arr, mac_addr);
+    -- ICMP : force type to icmp reply
+    v_response(5)(63 DOWNTO 56) := TO_UVEC(c_network_icmp_msg_type_reply, 8);
+    -- ICMP : force icmp checksum to 0
+    v_response(5)(15 DOWNTO  0) := TO_UVEC(0, 16);
+    RETURN v_response;
+  END;
+  
   FUNCTION func_network_total_header_response_udp(udp_arr  : t_network_total_header_32b_arr;
                                                   mac_addr : STD_LOGIC_VECTOR(c_network_eth_mac_addr_w-1 DOWNTO 0)) RETURN t_network_total_header_32b_arr IS
     VARIABLE v_response : t_network_total_header_32b_arr;
@@ -412,4 +695,17 @@ PACKAGE BODY common_network_total_header_pkg IS
     RETURN v_response;
   END;
   
+  FUNCTION func_network_total_header_response_udp(udp_arr  : t_network_total_header_64b_arr;
+                                                  mac_addr : STD_LOGIC_VECTOR(c_network_eth_mac_addr_w-1 DOWNTO 0)) RETURN t_network_total_header_64b_arr IS
+    VARIABLE v_response : t_network_total_header_64b_arr;
+  BEGIN
+    -- ETH, IP
+    v_response := func_network_total_header_response_ip(udp_arr, mac_addr);
+    -- UDP : swap udp dst port and udp src port
+    v_response(5)(63 DOWNTO 32) := udp_arr(5)(47 DOWNTO 32) & udp_arr(5)(63 DOWNTO 48);
+    -- UDP : force udp checksum to 0
+    v_response(5)(15 DOWNTO  0) := TO_UVEC(0, 16);
+    RETURN v_response;
+  END;
+  
 END common_network_total_header_pkg;