//
// Copyright (C) 2002, 2003, 2004, 2005 Yokogawa Electric Corporation, 
// INTAP(Interoperability Technology Association for Information 
// Processing, Japan), IPA (Information-technology Promotion Agency, Japan).
// All rights reserved.
// 
// Redistribution and use of this software in source and binary forms, with 
// or without modification, are permitted provided that the following 
// conditions and disclaimer are agreed and accepted by the user:
// 
// 1. Redistributions of source code must retain the above copyright 
// notice, this list of conditions and the following disclaimer.
// 
// 2. Redistributions in binary form must reproduce the above copyright 
// notice, this list of conditions and the following disclaimer in the 
// documentation and/or other materials provided with the distribution.
// 
// 3. Neither the names of the copyrighters, the name of the project which 
// is related to this software (hereinafter referred to as "project") nor 
// the names of the contributors may be used to endorse or promote products 
// derived from this software without specific prior written permission.
// 
// 4. No merchantable use may be permitted without prior written 
// notification to the copyrighters. However, using this software for the 
// purpose of testing or evaluating any products including merchantable 
// products may be permitted without any notification to the copyrighters.
// 
// 
// 
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHTERS, THE PROJECT AND 
// CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING 
// BUT NOT LIMITED THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 
// FOR A PARTICULAR PURPOSE, ARE DISCLAIMED.  IN NO EVENT SHALL THE 
// COPYRIGHTERS, THE PROJECT OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
// CONTRACT,STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
// THE POSSIBILITY OF SUCH DAMAGE.
// $TINY: acceptTooBigMesgOnlink.def,v 1.3 2002/03/05 02:59:10 masaxmasa Exp $
// 

#include "PMTU.def"

///////////////////////////////////
//
// Packets for HOST A or related A
//
///////////////////////////////////


// size 1500

FEM_icmp6_echo_request(
         echo_request_1500_from_A_LLA,
         _HETHER_c2nut,
        {
                 _SRC(v6("fe80::a"));
                 _DST(nutv6());
        },
        {
                 payload=ping_data_1452;
        }
)

FEM_icmp6_echo_reply(
         echo_reply_1500_to_A_LLA,
         _HETHER_nut2c,
        {
                 _SRC(nutv6());
                 _DST(v6("fe80::a"));
        },
        {
                 payload=ping_data_1452;
        }
)

// size 1400

FEM_icmp6_echo_request(
         echo_request_1400_from_A_LLA,
         _HETHER_c2nut,
        {
                 _SRC(v6("fe80::a"));
                 _DST(nutv6());
        },
        {
                 payload=ping_data_1352;
        }
)

FEM_icmp6_echo_reply(
         echo_reply_1400_to_A_LLA,
         _HETHER_nut2c,
        {
                 _SRC(nutv6());
                 _DST(v6("fe80::a"));
        },
        {
                 payload=ping_data_1352;
        }
)

//////////////////////////
// Too Big Messages

FEM_icmp6_packet_too_big(
        icmp6_TooBigMesg_1400_for_1500_A_LLA_C,
        _HETHER_c2nut,
                {
                _SRC(v6("fe80::c"));
                _DST(nutv6());
        },
                {
                MTU     = 1400;
                payload = TooBigData_1500_A_LLA;
        }
) 

Payload TooBigData_1500_A_LLA {
    data=substr(_PACKET_IPV6_NAME(echo_reply_1500_to_A_LLA),0,1232);
}

FEM_icmp6_packet_too_big(
        icmp6_TooBigMesg_1304_for_1400_A_LLA_C,
        _HETHER_c2nut,
                {
                _SRC(v6("fe80::c"));
                _DST(nutv6());
        },
                {
                MTU     = 1304;
                payload = TooBigData_1400_A_LLA;
        }
) 

Payload TooBigData_1400_A_LLA {
    data=substr(_PACKET_IPV6_NAME(echo_reply_1400_to_A_LLA),0,1232);
}

//////////////////////////
// Fragmented packets

// Echo Request
// size = 1400

PMTU_fragment( 
        frag_echo_request_1500_1st_mtu1400_A_LLA,
        _HETHER_c2nut,
                {
                NextHeader=44;
                _SRC(v6("fe80::a"));
                _DST(nutv6());
        },
                {
             NextHeader=58;
             FragmentOffset=0;
             MFlag=1;  
             Identification=10001;
        },
                {
        data=substr(_PACKET_IPV6_NAME(echo_request_1500_from_A_LLA),40,1352);
        }
)

PMTU_fragment(
        frag_echo_request_1500_2nd_mtu1400_A_LLA,
        _HETHER_c2nut,
                {
                NextHeader=44;
                _SRC(v6("fe80::a"));
                _DST(nutv6());
        },
                {
             NextHeader=58;
             FragmentOffset=169;
             MFlag=0;
             Identification=10001;
        },
                {
        data=substr(_PACKET_IPV6_NAME(echo_request_1500_from_A_LLA),1392,108);
        }
)


// size = 1304

PMTU_fragment( 
        frag_echo_request_1400_1st_mtu1304_A_LLA,
        _HETHER_c2nut,
                {
                NextHeader=44;
                _SRC(v6("fe80::a"));
                _DST(nutv6());
        },
                {
             NextHeader=58;
             FragmentOffset=0;
             MFlag=1;  
             Identification=10010;
        },
                {
        data=substr(_PACKET_IPV6_NAME(echo_request_1400_from_A_LLA),40,1256);
        }
)

PMTU_fragment(
        frag_echo_request_1400_2nd_mtu1304_A_LLA,
        _HETHER_c2nut,
                {
                NextHeader=44;
                _SRC(v6("fe80::a"));
                _DST(nutv6());
        },
                {
             NextHeader=58;
             FragmentOffset=157;
             MFlag=0;
             Identification=10010;
        },
                {
        data=substr(_PACKET_IPV6_NAME(echo_request_1400_from_A_LLA),1296,104);
        }
)

// Echo Reply
// size = 1400

PMTU_fragment( 
        frag_echo_reply_1500_1st_mtu1400_A_LLA,
        _HETHER_nut2c,
                {
                NextHeader=44;
                _SRC(nutv6());
                _DST(v6("fe80::a"));
        },
                {
             NextHeader=58;
             FragmentOffset=0;
             MFlag=1;  
             Identification=any;
        },
                {
        data=substr(_PACKET_IPV6_NAME(echo_reply_1500_to_A_LLA),40,1352);
        }
)

PMTU_fragment(
        frag_echo_reply_1500_2nd_mtu1400_A_LLA,
        _HETHER_nut2c,
                {
                NextHeader=44;
                _SRC(nutv6());
                _DST(v6("fe80::a"));
        },
                {
             NextHeader=58;
             FragmentOffset=169;
             MFlag=0;
             Identification=any;
        },
                {
        data=substr(_PACKET_IPV6_NAME(echo_reply_1500_to_A_LLA),1392,108);
        }
)


// size = 1304

PMTU_fragment( 
        frag_echo_reply_1400_1st_mtu1304_A_LLA,
        _HETHER_nut2c,
                {
                NextHeader=44;
                _SRC(nutv6());
                _DST(v6("fe80::a"));
        },
                {
             NextHeader=58;
             FragmentOffset=0;
             MFlag=1;  
             Identification=any;
        },
                {
        data=substr(_PACKET_IPV6_NAME(echo_reply_1400_to_A_LLA),40,1256);
        }
)

PMTU_fragment(
        frag_echo_reply_1400_2nd_mtu1304_A_LLA,
        _HETHER_nut2c,
                {
                NextHeader=44;
                _SRC(nutv6());
                _DST(v6("fe80::a"));
        },
                {
             NextHeader=58;
             FragmentOffset=157;
             MFlag=0;
             Identification=any;
        },
                {
        data=substr(_PACKET_IPV6_NAME(echo_reply_1400_to_A_LLA),1296,104);
        }
)

// size = 1280

PMTU_fragment( 
        frag_echo_reply_1400_1st_mtu1280_A_LLA,
        _HETHER_nut2c,
                {
                NextHeader=44;
                _SRC(nutv6());
                _DST(v6("fe80::a"));
        },
                {
             NextHeader=58;
             FragmentOffset=0;
             MFlag=1;  
             Identification=any;
        },
                {
        data=substr(_PACKET_IPV6_NAME(echo_reply_1400_to_A_LLA),40,1232);
        }
)

PMTU_fragment(
        frag_echo_reply_1400_2nd_mtu1280_A_LLA,
        _HETHER_nut2c,
                {
                NextHeader=44;
                _SRC(nutv6());
                _DST(v6("fe80::a"));
        },
                {
             NextHeader=58;
             FragmentOffset=154;
             MFlag=0;
             Identification=any;
        },
                {
        data=substr(_PACKET_IPV6_NAME(echo_reply_1400_to_A_LLA),1272,128);
        }
)

// size = 1280

PMTU_fragment( 
        frag_echo_reply_1500_1st_mtu1280_A_LLA,
        _HETHER_nut2c,
                {
                NextHeader=44;
                _SRC(nutv6());
                _DST(v6("fe80::a"));
        },
                {
             NextHeader=58;
             FragmentOffset=0;
             MFlag=1;  
             Identification=any;
        },
                {
        data=substr(_PACKET_IPV6_NAME(echo_reply_1500_to_A_LLA),40,1232);
        }
)

PMTU_fragment(
        frag_echo_reply_1500_2nd_mtu1280_A_LLA,
        _HETHER_nut2c,
                {
                NextHeader=44;
                _SRC(nutv6());
                _DST(v6("fe80::a"));
        },
                {
             NextHeader=58;
             FragmentOffset=154;
             MFlag=0;
             Identification=any;
        },
                {
        data=substr(_PACKET_IPV6_NAME(echo_reply_1500_to_A_LLA),1272,228);
        }
)



///////////////////////////////////
//
// Packets for HOST B or related B
//
///////////////////////////////////

// size 1500

FEM_icmp6_echo_request(
         echo_request_1500_from_B_LLA,
         _HETHER_b2nut,
        {
                 _SRC(v6("fe80::b"));
                 _DST(nutv6());
        },
        {
                 payload=ping_data_1452;
        }
)

FEM_icmp6_echo_reply(
         echo_reply_1500_to_B_LLA,
         _HETHER_nut2b,
        {
                 _SRC(nutv6());
                 _DST(v6("fe80::b"));
        },
        {
                 payload=ping_data_1452;
        }
)


//////////////////////////
// Fragmented packets

PMTU_fragment( 
        frag_echo_reply_1500_1st_mtu1400_B_LLA,
        _HETHER_nut2b,
                {
                NextHeader=44;
                _SRC(nutv6());
                _DST(v6("fe80::b"));
        },
                {
             NextHeader=58;
             FragmentOffset=0;
             MFlag=1;  
             Identification=any;
        },
                {
        data=substr(_PACKET_IPV6_NAME(echo_reply_1500_to_B_LLA),40,1352);
        }
)

PMTU_fragment(
        frag_echo_reply_1500_2nd_mtu1400_B_LLA,
        _HETHER_nut2b,
                {
                NextHeader=44;
                _SRC(nutv6());
                _DST(v6("fe80::b"));
        },
                {
             NextHeader=58;
             FragmentOffset=169;
             MFlag=0;
             Identification=any;
        },
                {
        data=substr(_PACKET_IPV6_NAME(echo_reply_1500_to_B_LLA),1392,108);
        }
)

//////////////////////////


PMTU_fragment( 
        frag_echo_reply_1500_1st_mtu1280_B_LLA,
        _HETHER_nut2b,
                {
                NextHeader=44;
                _SRC(nutv6());
                _DST(v6("fe80::b"));
        },
                {
             NextHeader=58;
             FragmentOffset=0;
             MFlag=1;  
             Identification=any;
        },
                {
        data=substr(_PACKET_IPV6_NAME(echo_reply_1500_to_B_LLA),40,1232);
        }
)

PMTU_fragment(
        frag_echo_reply_1500_2nd_mtu1280_B_LLA,
        _HETHER_nut2b,
                {
                NextHeader=44;
                _SRC(nutv6());
                _DST(v6("fe80::b"));
        },
                {
             NextHeader=58;
             FragmentOffset=154;
             MFlag=0;
             Identification=any;
        },
                {
        data=substr(_PACKET_IPV6_NAME(echo_reply_1500_to_B_LLA),1272,228);
        }
)

//////////////////////////////////////////////////////////////
// ns
// NUT's link local address
//           to
// TN's solicited Multicast address or TN's unicast address

FEM_icmp6_ns (
        ns_A_solnode,
        _HETHER_nut2a_solnode,
                {
                _SRC(nutv6());
                _DST(_IPV6_SOLNODE_MCAST(v6("fe80::a")));
                HopLimit=255;
        },
                {
                TargetAddress=v6("fe80::a");
                option=_SLLOPT_nut;
        }
)

// It would be wrong case
FEM_icmp6_ns (
        ns_A,
        _HETHER_nut2a,
                {
                _SRC(nutv6());
                _DST(v6("fe80::a"));
                HopLimit=255;
        },
                {
                TargetAddress=v6("fe80::a");
                option=_SLLOPT_nut;
        }
)

FEM_icmp6_ns (
        ns_A_C,
        _HETHER_nut2c,
                {
                _SRC(nutv6());
                _DST(v6("fe80::a"));
                HopLimit=255;
        },
                {
                TargetAddress=v6("fe80::a");
                option=_SLLOPT_nut;
        }
)

//  Global src address case
FEM_icmp6_ns (
        ns_srcGlobal_A_solnode,
        _HETHER_nut2c,
                {
                _SRC(NUT_GLOBAL_ADDRESS);
                _DST(_IPV6_SOLNODE_MCAST(v6("fe80::a")));
                HopLimit=255;
        },
                {
                TargetAddress=v6("fe80::a");
                option=_SLLOPT_nut;
        }
)  

// It would be wrong case
FEM_icmp6_ns (
        ns_srcGlobal_A,
        _HETHER_nut2a,
                {
                _SRC(NUT_GLOBAL_ADDRESS);
                _DST(v6("fe80::a"));
                HopLimit=255;
        },
                {
                TargetAddress=v6("fe80::a");
                option=_SLLOPT_nut;
        }
)  

FEM_icmp6_ns (
        ns_srcGlobal_A_C,
        _HETHER_nut2c,
                {
                _SRC(NUT_GLOBAL_ADDRESS);
                _DST(v6("fe80::a"));
                HopLimit=255;
        },
                {
                TargetAddress=v6("fe80::a");
                option=_SLLOPT_nut;
        }
)  


//FEM_icmp6_ns (
//        ns_A,
//        _HETHER_nut2a_oneof,
//                {
//                _SRC(nutv6());
//                _DST(oneof(_IPV6_SOLNODE_MCAST(v6("fe80::a")),v6("fe80::a")));
//                HopLimit=255;
//        },
//                {
//                TargetAddress=v6("fe80::a");
//                option=_SLLOPT_nut;
//        }
//)

FEM_icmp6_ns (
        ns_B_solnode,
        _HETHER_nut2b_solnode,
                {
                _SRC(nutv6());
                _DST(_IPV6_SOLNODE_MCAST(v6("fe80::b")));
                HopLimit=255;
        },
                {
                TargetAddress=v6("fe80::b");
                option=_SLLOPT_nut;
        }
)

FEM_icmp6_ns (
        ns_B,
        _HETHER_nut2b,
                {
                _SRC(nutv6());
                _DST(v6("fe80::b"));
                HopLimit=255;
        },
                {
                TargetAddress=v6("fe80::b");
                option=_SLLOPT_nut;
        }
)


//
// ns
// NUT's global address


FEM_icmp6_ns (
        ns_srcGlobal_B_solnode,
        _HETHER_nut2b_solnode,
                {
                _SRC(NUT_GLOBAL_ADDRESS);
                _DST(_IPV6_SOLNODE_MCAST(v6("fe80::b")));
                HopLimit=255;
        },
                {
                TargetAddress=v6("fe80::b");
                option=_SLLOPT_nut;
        }
)  

FEM_icmp6_ns (
        ns_srcGlobal_B,
        _HETHER_nut2b,
                {
                _SRC(NUT_GLOBAL_ADDRESS);
                _DST(v6("fe80::b"));
                HopLimit=255;
        },
                {
                TargetAddress=v6("fe80::b");
                option=_SLLOPT_nut;
        }
)  

///////////////////////////////////////////// 
// Porxy Neighbore Advertisment For B
// Targetaddress TN's link local address
             
//
// To Linklocal address

FEM_icmp6_na (
        na_B,
        _HETHER_b2nut,
                {
                _SRC(v6("fe80::b"));
                _DST(nutv6());
                HopLimit=255;
        },
                {
                SFlag=1;
                OFlag=1;
                TargetAddress=v6("fe80::b");
                option=_TLLOPT_b;
        }
)

//
// To Global Address address
 
FEM_icmp6_na (
        na_dstGlobal_B,
        _HETHER_b2nut,
                {
                _SRC(v6("fe80::b"));
	        _DST(NUT_GLOBAL_ADDRESS);
                HopLimit=255;
        },
                {
                SFlag=1;
                OFlag=1;
                TargetAddress=tnv6();
                option=_TLLOPT_b;
        }
)


///////////////////////////////////////////
// Proxy Neighbor Advertisement for A by C

//
// To Linklocal address

FEM_icmp6_na (
        na_A_C,
        _HETHER_c2nut,
                {
                _SRC(v6("fe80::a"));
                _DST(nutv6());
                HopLimit=255;
        },
                {
                SFlag=1;
                OFlag=0;
                TargetAddress=v6("fe80::a");
                option=_TLLOPT_c;
        }
)

//
// To Global address
 
FEM_icmp6_na (
        na_dstGlobal_A_C,
        _HETHER_c2nut,
                {
                _SRC(v6("fe80::a"));
	        _DST(NUT_GLOBAL_ADDRESS);
                HopLimit=255;
        },
                {
                SFlag=1;
                OFlag=0;
                TargetAddress=v6("fe80::a");
                option=_TLLOPT_c;
        }
)

_HETHER_define(_HETHER_a2nut,  ether("00:00:00:00:00:0a"), nutether())
_HETHER_define(_HETHER_b2nut,  ether("00:00:00:00:00:0b"), nutether())
_HETHER_define(_HETHER_c2nut,  ether("00:00:00:00:00:0c"), nutether())
_HETHER_define(_HETHER_nut2a,  nutether(), ether("00:00:00:00:00:0a"))
_HETHER_define(_HETHER_nut2b,  nutether(), ether("00:00:00:00:00:0b"))
_HETHER_define(_HETHER_nut2c,  nutether(), ether("00:00:00:00:00:0c"))
_HETHER_define(_HETHER_nut2a_solnode,  nutether(), _ETHER_SOLNODE_MCAST(v6("fe80::a")))
_HETHER_define(_HETHER_nut2b_solnode,  nutether(), _ETHER_SOLNODE_MCAST(v6("fe80::b")))
_HETHER_define(_HETHER_nut2a_oneof,  nutether(), oneof(ether("00:00:00:00:00:0a"),  _ETHER_SOLNODE_MCAST(v6("fe80::a"))))
_HETHER_define(_HETHER_nut2b_oneof,  nutether(), oneof(ether("00:00:00:00:00:0b"),  _ETHER_SOLNODE_MCAST(v6("fe80::b"))))

_TLLOPT_define(_TLLOPT_b,  ether("00:00:00:00:00:0b"))
_TLLOPT_define(_TLLOPT_c,  ether("00:00:00:00:00:0c"))

