#!/usr/bin/perl
#
# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
# Yokogawa Electric Corporation.
# 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.
# 
# 5. The copyrighters, the project and the contributors may prohibit
#    the use of this software at any time.
# 
# 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.
#
# $TAHI: ct-ikev2/4-SGW-R/IKEv2-SGW-R-1-1-5-4.seq,v 1.2 2008/03/13 05:55:05 ohgushi Exp $
#
################################################################

BEGIN
{
	push(@INC, '..');
}

END { }

use IKEv2;
use strict;


my $remote	= 'common_remote_index';


my $session = undef;
my $ret = undef;
my $str = undef;

my $ike_sa_init_req_param = undef;
my $ike_sa_init_resp_param = undef;

my @local_ike_sa_init_req = undef;
my $invalid_payload = undef;
my @local_ike_sa_init_resp = undef;


kLogHTML('<FONT COLOR="#FF0000" SIZE="+1"><U><B>TEST SETUP</B></U></FONT>');

#------------------------------#
# register IKEv2.pm            #
#------------------------------#
unless (IKEv2initialize('SGW', 'SGW')) {
	IKEv2exitFatal('<FONT COLOR="#ff0000">IKEv2 module initializing failure</FONT>');
}


#------------------------------#
# configure TN                 #
#------------------------------#
unless (IKEv2setupTN()) {
	IKEv2exitFatal('<FONT COLOR="#ff0000">TN setup failure</FONT>');
}


#------------------------------#
# configure NUT                #
#------------------------------#
unless (IKEv2setupNUT()) {
	IKEv2exitFatal('<FONT COLOR="#ff0000">NUT setup failure</FONT>');
}

kLogHTML('<FONT COLOR="#FF0000" SIZE="+1"><U><B>TEST PROCEDURE</B></U></FONT>');
kLogHTML('<FONT COLOR="#000000" SIZE="+1"><U><B>Part A:Invalid payload type 1 and critical flag is set.</B></U></FONT>');


#------------------------------#
# prepare session handler      #
#------------------------------#
$session = IKEv2create_session('common_remote_index');
unless (defined($session)) {
	IKEv2exitFatal('<FONT COLOR="#ff0000">IKEv2 session creation failure</FONT>');
}



#-------------------------------------------------#
# prepare IKE_SA_INIT req include invaled payload #
#-------------------------------------------------#
$invalid_payload = { 
        # INVALID Payload
        'self'          => 'UNDEFINED',       # *** MUST BE HERE ***
        'nexttype'      => undef,     # Next Payload
        'critical'      => '1',       # Critical
        'reserved'      => undef,     # RESERVED
        'length'        => undef,     # Payload Length
        'type'          => '1',       # This value is set to previous payload's Next Payload
};

my $common_ike_sa_init_req = $gen_ike_sa_init_req->{'common_remote_index'};
@local_ike_sa_init_req = @{$common_ike_sa_init_req};
# add invalid payload
for (my $i = 0; $i < scalar(@local_ike_sa_init_req); $i++) {
        if ($local_ike_sa_init_req[$i]->{'self'} eq 'SA') {
                splice(@local_ike_sa_init_req, $i, 0, $invalid_payload);
                last;
        }
}
$gen_ike_sa_init_req->{'SGW-R-1-1-5-4.A.1'} = \@local_ike_sa_init_req;



#--------------------------------------#
# send IKE_SA_INIT request to NUT      #
#--------------------------------------#
$str  = '<PRE>';
$str .= "    (R)             (I)\n";
$str .= "    NUT             TN1\n";
$str .= "     |               |\n";
$str .= "     |<--------------| IKE_SA_INIT request (HDR, P, SAi1, KEi, Ni)\n";
$str .= "     |               |\n";
$str .= "     V               V";
$str .= '</PRE>';

kLogHTML($str);


$ike_sa_init_req_param = devel_IKEv2send_IKE_SA_INIT_request($session,
                                                             'SGW-R-1-1-5-4.A.1');
unless (defined($ike_sa_init_req_param)) {
	kLogHTML(kDump_Common_Error());
	IKEv2exitFatal('<FONT COLOR="#ff0000">Can\'t send IKE_SA_INIT request.</FONT>');
}


#-------------------------------------------------#
# prepare IKE_SA_INIT resp include Notify payload #
#-------------------------------------------------#
my $tmp_notify_payload =
{       # Notify Payload
        'nexttype'      => '0', # Next Payload
        'critical'      => '0', # Critical
        'reserved'      => '0', # RESERVED
        'length'        => '10', # Payload Length
        'id'            => 'IKE', # Protocol ID
        'spiSize'       => '0', # SPI Size
        'type'          => 'UNSUPPORTED_CRITICAL_PAYLOAD',# Notify Type
        'spi'           => '0', # SPI
        'data'          => '1', # Notification Data
};
my $common_ike_sa_init_resp = $exp_ike_sa_init_resp->{'common_remote_index'};
@local_ike_sa_init_resp = @{$common_ike_sa_init_resp};
# remove payload without HDR
@local_ike_sa_init_resp = grep {
                my $ret = 0;
                if ($_->{'self'} eq 'HDR') { $ret = 1; }
                $ret;
        } @local_ike_sa_init_resp;
# add Notify payload 
for (my $i = 0; $i < scalar(@local_ike_sa_init_resp); $i++) {
        if ($local_ike_sa_init_resp[$i]->{'self'} eq 'HDR') {
                $local_ike_sa_init_resp[$i]->{'respSPI'} = undef;
                splice(@local_ike_sa_init_resp, $i+1, 0, $tmp_notify_payload);
                last;
        }
}
#set correct nexttype
for (my $i = 0; $i < scalar(@local_ike_sa_init_resp); $i++) {
        my $payload = $local_ike_sa_init_resp[$i];

        if ($payload->{'self'} eq 'HDR') {
                my $next = $local_ike_sa_init_resp[$i+1]; 
                unless (defined($next)) {
                        $payload->{'nexttype'} = '0';
                        next;
                }
                if ($payload->{'nexttype'} eq $next->{'self'}) {
                        next;
                }
                $payload->{'nexttype'} = $next->{'self'};
        }
}
$exp_ike_sa_init_resp->{'SGW-R-1-1-5-4.A.2'} = \@local_ike_sa_init_resp;



#--------------------------------------#
# receive IKE_SA_INIT response by NUT  #
#--------------------------------------#
$str  = '<PRE>';
$str .= "    (R)             (I)\n";
$str .= "    NUT             TN1\n";
$str .= "     |               |\n";
$str .= "     |-------------->| IKE_SA_INIT response (HDR, N(UNSUPPORTED_CRITICAL_PAYLOAD))\n";
$str .= "     |               |\n";
$str .= "     V               V";
$str .= '</PRE>';

kLogHTML($str);


$ike_sa_init_resp_param = devel_IKEv2receive_IKE_SA_INIT_response($session,
                                                                  'SGW-R-1-1-5-4.A.2',
                                                                  $ike_sa_init_req_param);
unless (defined($ike_sa_init_resp_param)) {
	kLogHTML(kDump_Common_Error());
	kLogHTML('<FONT COLOR="#ff0000">Can\'t observe IKE_SA_INIT response.</FONT>');
	IKEv2exitFail();
}



#--------------------------------------#
# exit with cleanup                    #
#--------------------------------------#
IKEv2exitPass();

#
# perldoc
#
########################################################################
__END__
