//
// $Copyright$
//
// $Name:  $
//
// $Id: HTR_common.def,v 1.1.1.1 2000/10/31 22:38:51 sekiya Exp $
//
#ifndef IPSEC_HTR_COMMON_DEF
#define IPSEC_HTR_COMMON_DEF

#include "./ipsecaddr.def"

#if (IPSEC_IPVERSION == 4)

#define vX(x)	v4(x)
#define FEM_icmpX_echo_request		FEM_icmp4_echo_request
#define FEM_icmpX_echo_reply		FEM_icmp4_echo_reply
#define FEM_icmpX_echo_request_exth	FEM_icmp4_echo_request_exth
#define FEM_icmpX_echo_reply_exth	FEM_icmp4_echo_reply_exth
#define _HDR_IPVX_NAME			_HDR_IPV4_NAME
#define _ICMPVX_NAME			_ICMPV4_NAME

#ifndef IPSEC_ECHO_DATA
#define IPSEC_ECHO_DATA echo_data24
#endif

#else /* default V6 */

#define vX(x)	v6(x)
#define FEM_icmpX_echo_request		FEM_icmp6_echo_request
#define FEM_icmpX_echo_reply		FEM_icmp6_echo_reply
#define FEM_icmpX_echo_request_exth	FEM_icmp6_echo_request_exth
#define FEM_icmpX_echo_reply_exth	FEM_icmp6_echo_reply_exth
#define _HDR_IPVX_NAME			_HDR_IPV6_NAME
#define _ICMPVX_NAME			_ICMPV6_NAME

#ifndef IPSEC_ECHO_DATA
#define IPSEC_ECHO_DATA echo_data8
#endif

#endif

//======================================================================

_HETHER_define(hether_router2nut,
	ether(IPSEC_ROUTER_NET3_MAC_ADDR),
	nutether()
)

_HETHER_define(hether_nut2router,
	nutether(),
	ether(IPSEC_ROUTER_NET3_MAC_ADDR)
)

//
// NS or ARP Request
//

#if (IPSEC_IPVERSION == 4)
FEM_hdr_arp(
	ns_to_router,
        _HETHER_nut2broadcast,
        {
                Operation=1;
                SenderHAddr=nutether();
                SenderPAddr=v4(IPSEC_NUT_NET3_ADDR);
                TargetHAddr=any; // not only 00:00:00:00:00:00
                                 // but also ff:ff:ff:ff:ff:ff (same as ether_src)
                                 // is allowed
                TargetPAddr=v4(IPSEC_ROUTER_NET3_ADDR);
        }
)

#else
_HETHER_define(hether_nut2routersolnode,
	nutether(),
	oneof(_ETHER_SOLNODE_MCAST(v6(IPSEC_ROUTER_NET3_ADDR)),
	      ether(IPSEC_ROUTER_NET3_MAC_ADDR) )
)

FEM_icmp6_ns(
	ns_to_router,
	hether_nut2routersolnode,
	{
		_SRC(oneof(v6(IPSEC_NUT_NET3_ADDR), nutv6()));
		_DST(oneof(v6(IPSEC_ROUTER_NET3_ADDR), _IPV6_SOLNODE_MCAST(v6(IPSEC_ROUTER_NET3_ADDR))));
		HopLimit = 255;
	},
	{
		TargetAddress = v6(IPSEC_ROUTER_NET3_ADDR);
		option = _SLLOPT_nut;
	}
)
#endif

//
// NA or ARP Reply
//

#if (IPSEC_IPVERSION == 4)
FEM_hdr_arp(
	na_from_router,
        hether_router2nut,
        {
                Operation=2;
                SenderHAddr=ether(IPSEC_ROUTER_NET3_MAC_ADDR);
                SenderPAddr=v4(IPSEC_ROUTER_NET3_ADDR);
                TargetHAddr=nutether();
                TargetPAddr=v4(IPSEC_NUT_NET3_ADDR);
        }
)
#else
_TLLOPT_define(tllopt_router, ether(IPSEC_ROUTER_NET3_MAC_ADDR))

FEM_icmp6_na(
	na_from_router,
	hether_router2nut,
	{
		_SRC(v6(IPSEC_ROUTER_NET3_ADDR));
		_DST(v6(IPSEC_NUT_NET3_ADDR));
		HopLimit = 255;
	},
	{
		RFlag = 1;
		SFlag = 1;
		OFlag = 1;
		TargetAddress = v6(IPSEC_ROUTER_NET3_ADDR);
		option = tllopt_router;
	}
)
#endif

//======================================================================
//
// Echo Request from Router
//

FEM_icmpX_echo_request(
	echo_request_from_router,
	hether_router2nut,
	{
		_SRC(vX(IPSEC_ROUTER_NET3_ADDR));
		_DST(vX(IPSEC_NUT_NET3_ADDR));
	},
	{
		payload = IPSEC_ECHO_DATA;
	}
)

//======================================================================
//
// Echo Reply to Router
//

FEM_icmpX_echo_reply(
	echo_reply_to_router,
	hether_nut2router,
	{
		_SRC(vX(IPSEC_NUT_NET3_ADDR));
		_DST(vX(IPSEC_ROUTER_NET3_ADDR));
	},
	{
		payload = IPSEC_ECHO_DATA;
	}
)

//======================================================================
//
// Echo Request from Host1
//

FEM_icmpX_echo_request(
	echo_request_from_host1,
	hether_router2nut,
	{
		_SRC(vX(IPSEC_HOST1_NET5_ADDR));
		_DST(vX(IPSEC_NUT_NET3_ADDR));
	},
	{
		payload = IPSEC_ECHO_DATA;
	}
)

//======================================================================
//
// Echo Reply to Host1
//

FEM_icmpX_echo_reply(
	echo_reply_to_host1,
	hether_nut2router,
	{
		_SRC(vX(IPSEC_NUT_NET3_ADDR));
		_DST(vX(IPSEC_HOST1_NET5_ADDR));
	},
	{
		payload = IPSEC_ECHO_DATA;
	}
)

//======================================================================
//
// Echo Request from Host1 (before Fragment)
//

FEM_icmpX_echo_request(
	echo_request_from_host1_big,
	hether_router2nut,
	{
		_SRC(vX(IPSEC_HOST1_NET5_ADDR));
		_DST(vX(IPSEC_NUT_NET3_ADDR));
	},
	{
		payload = echo_data_big;
	}
)

#if (IPSEC_IPVERSION == 4)
#else
//
// Echo Request from Host1 (Fragment 1st)
//

FEM_hdr_ipv6_exth(
	echo_request_from_host1_1st,
	hether_router2nut,
	{
		_SRC(v6(IPSEC_HOST1_NET5_ADDR));
		_DST(v6(IPSEC_NUT_NET3_ADDR));
	},
	{
		header = _HDR_IPV6_NAME(echo_request_from_host1_1st);
		exthdr = frag_req_1st;
		upper = payload_req_1st;
	}
)

//
// Echo Request from Host1 (Fragment 2nd)
//

FEM_hdr_ipv6_exth(
	echo_request_from_host1_2nd,
	hether_router2nut,
	{
		_SRC(v6(IPSEC_HOST1_NET5_ADDR));
		_DST(v6(IPSEC_NUT_NET3_ADDR));
	},
	{
		header = _HDR_IPV6_NAME(echo_request_from_host1_2nd);
		exthdr = frag_req_2nd;
		upper = payload_req_2nd;
	}
)
#endif

//======================================================================
//
// Echo Reply to Host1 (before Fragment)
//

FEM_icmpX_echo_reply(
	echo_reply_to_host1_big,
	hether_nut2router,
	{
		_SRC(vX(IPSEC_NUT_NET3_ADDR));
		_DST(vX(IPSEC_HOST1_NET5_ADDR));
	},
	{
		payload = echo_data_big;
	}
)

#if (IPSEC_IPVERSION == 4)
#else
//
// Echo Reply to Host1 (Fragment 1st)
//

FEM_hdr_ipv6_exth(
	echo_reply_to_host1_1st,
	hether_nut2router,
	{
		_SRC(v6(IPSEC_NUT_NET3_ADDR));
		_DST(v6(IPSEC_HOST1_NET5_ADDR));
	},
	{
		header = _HDR_IPV6_NAME(echo_reply_to_host1_1st);
		exthdr = frag_rep_1st;
		upper = payload_rep_1st;
	}
)


//
// Echo Reply to Host1 (Fragment 2nd)
//

FEM_hdr_ipv6_exth(
	echo_reply_to_host1_2nd,
	hether_nut2router,
	{
		_SRC(v6(IPSEC_NUT_NET3_ADDR));
		_DST(v6(IPSEC_HOST1_NET5_ADDR));
	},
	{
		header = _HDR_IPV6_NAME(echo_reply_to_host1_2nd);
		exthdr = frag_rep_2nd;
		upper = payload_rep_2nd;
	}
)
#endif

//======================================================================
//
// Default Payload Data ("EchoData")
//

Payload echo_data8 {
	data = { 0x45, 0x63, 0x68, 0x6f, 0x44, 0x61, 0x74, 0x61};
}

Payload echo_data24 {
	data = { 0x45, 0x63, 0x68, 0x6f, 0x44, 0x61, 0x74, 0x61};
	data = { 0x45, 0x63, 0x68, 0x6f, 0x44, 0x61, 0x74, 0x61};
	data = { 0x45, 0x63, 0x68, 0x6f, 0x44, 0x61, 0x74, 0x61};
}

//======================================================================
//
// Echo Data 1 ("Data 1")
//

Payload echo_data_1 {
        data = { 0x44, 0x61, 0x74, 0x61, 0x20, 0x31 };
}

//======================================================================
//
// Echo Data 2 ("Data 2")
//

Payload echo_data_2 {
        data = { 0x44, 0x61, 0x74, 0x61, 0x20, 0x32 };
}

//======================================================================
//
// Echo Data for Fragment
//

Payload echo_data_big {
	data = repeat(0xff, 1702);
}

Hdr_Fragment frag_req_1st {
	NextHeader = 58;	// ICMP
	FragmentOffset = 0;
	MFlag = 1;
	Identification = 0x0001;
}

Hdr_Fragment frag_req_2nd {
	NextHeader = 58;	// ICMP
	FragmentOffset = 181;
	MFlag = 0;
	Identification = 0x0001;
}

Payload payload_req_1st {
	data = substr(_PACKET_IPV6_NAME(echo_request_from_host1_big), 40, 1448);
}

Payload payload_req_2nd {
	data = right(_PACKET_IPV6_NAME(echo_request_from_host1_big), 1488);
}

Hdr_Fragment frag_rep_1st {
	NextHeader = 58;	// ICMP
	FragmentOffset = 0;
	MFlag = 1;
	Identification = any;
}

Hdr_Fragment frag_rep_2nd {
	NextHeader = 58;	// ICMP
	FragmentOffset = 181;
	MFlag = 0;
	Identification = any;
}

Payload payload_rep_1st {
	data = substr(_PACKET_IPV6_NAME(echo_reply_to_host1_big), 40, 1448);
}

Payload payload_rep_2nd {
	data = right(_PACKET_IPV6_NAME(echo_reply_to_host1_big), 1488);
}

#endif
