# $Copyright$
# $Id: DHCPv6_common.pm,v 1.17 2007/09/20 02:00:55 hide Exp $
# $TAHI: dhcpv6.p2/DHCPv6_common.pm,v 1.17 2007/09/20 02:00:55 hide Exp $
#
#################################################################
package DHCPv6_common;
use Exporter;
use MIME::Base64;
use Digest::HMAC_MD5 qw(hmac_md5 hmac_md5_hex);
use V6evalTool;
use DHCPv6_config;
use strict;
use vars qw(
@ISA
@EXPORT
$TRUE
$FALSE
$DUID_CLIENT
$NUTRELAY1_LINK0_GLOBAL_UCAST
$NUTRELAY1_LINK1_GLOBAL_UCAST
$SERVER1_GLOBAL_UCAST
$RELAY2_GLOBAL_UCAST
$CID_OPTION
$SID_OPTION
$IA_NA_OPTION
$IA_NA_OPTION1
$IA_PD_OPTION
$IA_PD_OPTION1
$IA_TA_OPTION
$DNS_SVR_OPTION
$DNS_LST_OPTION
$OptionRequest_OPTION
$Preference_OPTION
$ElapsedTime_OPTION
$Authentication_OPTION
$Authentication_OPTION2
$ServerUnicast_OPTION
$RapidCommit_OPTION
$UserClass_OPTION
$VendorClass_OPTION
$VendorSpecificInfo_OPTION
$IID_OPTION
$ReconfigureMessage_OPTION
$ReconfigureAccept_OPTION
$RELAY_Msg_OPTION
$StatusCode_OPTION
$AUTH_OPTION_REQUIRED
$SOL_MAX_DELAY
$SOL_TIMEOUT
$SOL_MAX_RT
$REQ_TIMEOUT
$REQ_MAX_RT
$REQ_MAX_RC
$CNF_MAX_DELAY
$CNF_TIMEOUT
$CNF_MAX_RT
$CNF_MAX_RD
$REN_TIMEOUT
$REN_MAX_RT
$REB_TIMEOUT
$REB_MAX_RT
$INF_MAX_DELAY
$INF_TIMEOUT
$INF_MAX_RT
$REL_TIMEOUT
$REL_MAX_RC
$DEC_TIMEOUT
$DEC_MAX_RC
$REC_TIMEOUT
$REC_MAX_RC
$RAND
$CMP_CID
$CMP_SID
$CMP_IA_NA
$CMP_IA_TA
$CMP_IA_ADD
$CMP_ORO
$CMP_PREF
$CMP_ETIME
$CMP_RELAYMSG
$CMP_AUTH
$CMP_SVRUNICAST
$CMP_STATUS_CODE
$CMP_RAPIDCOMMIT
$CMP_USER_CLASS
$CMP_VENDER_CLASS
$CMP_VENDER_SPEC
$CMP_IID
$CMP_RECONF_MSG
$CMP_RECONF_ACCEPT
$CMP_IA_PD
$CMP_IA_PREFIX
$CMP_DNS_SVR
$CMP_DNS_LST
$CMP_NTP_SVR
$CMP_NTP_TZ
$CMP_SIP_D
$CMP_SIP_A
$CMP_TRANS_ID
);
@ISA = qw(Exporter);
@EXPORT = qw(
wait_for_dhcp6frame_cpp
wait_for_dhcp6frame
wait_for_solicit
wait_for_advertise
wait_for_request
wait_for_confirm
wait_for_renew
wait_for_rebind
wait_for_release
wait_for_reply
wait_for_decline
wait_for_reconfigure
wait_for_information_request
wait_for_relay_forward_solicit
wait_for_relay_forward_request
wait_for_relay_forward_confirm
wait_for_relay_forward_renew
wait_for_relay_forward_rebind
wait_for_relay_forward_release
wait_for_relay_forward_decline
wait_for_relay_reply_reply
wait_for_relay_reply_advertise
wait_for_relay_reply_relay
wait_for_relay_forward
vRecvPacket
send_solicit
send_advertise
send_advertise1
send_advertise2
send_request
send_confirm
send_renew
send_rebind
send_decline
send_release
send_reply
send_reply2
send_reply3
send_reconfigure
send_information_request
dhcpExitPass
dhcpExitIgnore
dhcpExitNS
dhcpExitError
dhcpExitFail
dhcpReset
dhcpCltInit
dhcpCltStart
dhcpCltRestart
ck_IAoptions
dhcpSvrInit
dhcpSvrInitS
SetNUTAddr
ifDown
ifUp
dhcpRelayInit
send_relay_forward
send_relay_forward_request
send_relay_reply
chkMsgAfterRelay
ckRelayMsgHopLimit
ckRelayForwardMsgHopCount
ckRelayForwardPeerAddress
CompareTimeUpdateCompletely
initial_ra_w_ping
ping_test
ping_test_addr2
ping_test_nut1
ping_nut_test
check_equal
check_dest_ipaddress
check_ipaddr_local
compare_message
compare_id
compare_iaid
get_IA_NA_number
get_IA_PD_number
get_IA_Prefix_number
get_OptRequstCode
lookup_OptRequestCode
compare_options
get_nut_link_number
get_value
get_udp_destport
getElapsedtime
gen_cpp_inforeq
parse_IAPD_option
parse_IAPrefix_option
options_exist
createPacketDefinitionFile
parse_message
check_DUID
check_FieldValueinOption
check_valueofAnyFieldInOption
chk_statuscode
get_statuscode_string
CheckTimeOfPrefixOP
CheckIfExistOP
CheckIfExistOPwithIndex
GetFieldValueInMsg
ck_IAPD_prefix_options
ck_IAPDoptions
CheckMessageInRelayOption
ckRelayForwardLinkAddress
ChkFuncSupport
ChkConfig
Ascii2Hex
Ascii2Base64
SharedSecretKeyCheck
ReplayDetectCounter
check_Auth_MD5
clear_options
$TRUE
$FALSE
$DUID_CLIENT
$NUTRELAY1_LINK0_GLOBAL_UCAST
$NUTRELAY1_LINK1_GLOBAL_UCAST
$SERVER1_GLOBAL_UCAST
$RELAY2_GLOBAL_UCAST
$CID_OPTION
$SID_OPTION
$IA_NA_OPTION
$IA_NA_OPTION1
$IA_PD_OPTION
$IA_PD_OPTION1
$IA_TA_OPTION
$DNS_SVR_OPTION
$DNS_LST_OPTION
$OptionRequest_OPTION
$Preference_OPTION
$ElapsedTime_OPTION
$Authentication_OPTION
$Authentication_OPTION2
$ServerUnicast_OPTION
$RapidCommit_OPTION
$UserClass_OPTION
$VendorClass_OPTION
$VendorSpecificInfo_OPTION
$IID_OPTION
$ReconfigureMessage_OPTION
$ReconfigureAccept_OPTION
$RELAY_Msg_OPTION
$StatusCode_OPTION
$AUTH_OPTION_REQUIRED
$SOL_MAX_DELAY
$SOL_TIMEOUT
$SOL_MAX_RT
$REQ_TIMEOUT
$REQ_MAX_RT
$REQ_MAX_RC
$CNF_MAX_DELAY
$CNF_TIMEOUT
$CNF_MAX_RT
$CNF_MAX_RD
$REN_TIMEOUT
$REN_MAX_RT
$REB_TIMEOUT
$REB_MAX_RT
$INF_MAX_DELAY
$INF_TIMEOUT
$INF_MAX_RT
$REL_TIMEOUT
$REL_MAX_RC
$DEC_TIMEOUT
$DEC_MAX_RC
$REC_TIMEOUT
$REC_MAX_RC
$RAND
$CMP_CID
$CMP_SID
$CMP_IA_NA
$CMP_IA_TA
$CMP_IA_ADD
$CMP_ORO
$CMP_PREF
$CMP_ETIME
$CMP_RELAYMSG
$CMP_AUTH
$CMP_SVRUNICAST
$CMP_STATUS_CODE
$CMP_RAPIDCOMMIT
$CMP_USER_CLASS
$CMP_VENDER_CLASS
$CMP_VENDER_SPEC
$CMP_IID
$CMP_RECONF_MSG
$CMP_RECONF_ACCEPT
$CMP_IA_PD
$CMP_IA_PREFIX
$CMP_DNS_SVR
$CMP_DNS_LST
$CMP_NTP_SVR
$CMP_NTP_TZ
$CMP_SIP_D
$CMP_SIP_A
$CMP_TRANS_ID
$LISTEN_UDPPORT_CLT
$LISTEN_UDPPORT_SVRRELAY
);
sub wait_for_dhcp6frame_cpp($$$$);
sub wait_for_dhcp6frame($$$);
sub wait_for_advertise($$);
sub wait_for_reply($$);
sub wait_for_reconfigure($$);
sub wait_for_relay_reply_advertise($$$);
sub wait_for_relay_reply_reply($$;$);
sub wait_for_relay_reply_relay($$$);
sub wait_for_relay_forward_solicit($$);
sub wait_for_relay_forward_request($$);
sub wait_for_relay_forward_confirm($$);
sub wait_for_relay_forward_renew($$);
sub wait_for_relay_forward_rebind($$);
sub wait_for_relay_forward_release($$);
sub wait_for_relay_forward_decline($$);
sub wait_for_relay_forward($$$);
sub wait_for_solicit($$);
sub wait_for_request($$);
sub wait_for_confirm($$);
sub wait_for_renew($$);
sub wait_for_rebind($$);
sub wait_for_decline($$);
sub wait_for_information_request($$);
sub wait_for_release($$);
sub vRecvPacket($$$$@);
sub send_solicit($$$);
sub send_confirm($$$$);
sub send_renew($$$$);
sub send_rebind($$$$);
sub send_release($$$$);
sub send_decline($$$$);
sub send_information_request($$$$);
sub send_request($$$$);
sub send_advertise($$$$);
sub send_advertise2($$$$);
sub send_reply($$$$);
sub send_reply2($$$$);
sub send_reply3($$$$);
sub send_reconfigure($$$$);
sub get_value($$$;$);
sub getElapsedtime($);
sub get_nut_link_number($);
sub get_OptRequstCode($);
sub lookup_OptRequestCode($$);
sub initial_ra_w_ping($$);
sub ping_test($);
sub ping_test_addr2($);
sub ping_test_nut1($);
sub ping_nut_test($;$$$);
sub check_equal($$;$);
sub check_dest_ipaddress($);
sub check_ipaddr_local($$);
# for exit values
sub dhcpExitPass();
sub dhcpExitIgnore();
sub dhcpExitNS();
sub dhcpExitSkip();
sub dhcpExitError($);
sub dhcpExitFail(;$);
sub dhcpReset();
sub dhcpCltInit();
sub dhcpCltStart();
sub dhcpCltRestart();
#for interface
sub ifDown($);
sub ifUp($);
# for retransmission
sub compare_message($$);
sub compare_id($$$);
#sub get_iaid($$);
sub compare_iaid($$$);
sub get_IA_NA_number($);
sub get_IA_PD_number($);
sub get_IA_Prefix_number($);
sub parse_IAPD_option($);
sub parse_IAPrefix_option($);
sub get_udp_destport($);
sub gen_cpp_inforeq($);
#check functions
sub getMsgTypeLocStr($);
sub compare_options($$$);
sub compare_option($$$$);
sub clear_options();
sub options_exist($$);
sub createPacketDefinitionFile($);
sub get_statuscode_string($);
sub get_optname_string($);
sub parse_message($);
sub ck_IAoptions($$$);
sub check_DUID($$$);
sub check_FieldValueinOption($$$$);
sub check_valueofAnyFieldInOption($$$$);
sub chk_statuscode($$);
sub CheckTimeOfPrefixOP($$);
sub CheckMessageInRelayOption($$);
sub CheckIfExistOP($$);
sub CheckIfExistOPwithIndex($$);
sub GetFieldValueInMsg($$);
sub ck_IAPD_prefix_options($$);
sub ck_IAPDoptions($$$);
sub ckRelayForwardMsgHopCount ($$);
sub ckRelayMsgHopLimit ($$);
sub ckRelayForwardPeerAddress ($$);
sub ckRelayForwardLinkAddress($$);
sub CompareTimeUpdateCompletely($$$$);
#setup the NUT(server)
sub dhcpSvrInit($);
sub dhcpSvrInitS($);
sub SetNUTAddr($$$$);
# for relay-agent
sub dhcpRelayInit($);
sub send_relay_forward($$);
sub send_relay_forward_request($$$$);
sub parse_relay_message($);
sub send_relay_reply($$$$);
sub chkMsgAfterRelay($$);
#internal fuction
sub message_output($$$);
#judgement whether make the DUID test;
sub ChkFuncSupport($);
#check configuration parametor
sub ChkConfig($);
#exchange Ascii to XXXX
sub Ascii2Hex($);
sub Ascii2Base64($);
#Global Constant define
$TRUE = 1;
$FALSE = undef;
#Shared Secret Key type check
sub SharedSecretKeyCheck($$);
#Increment Replay DetectCounter
sub ReplayDetectCounter($);
#calculate MD5
sub check_Auth_MD5($$);
sub get_Opt_String($$$$);
#Debug Option
my $DHCP_CHECK_DEBUG = $TRUE;
#DUID constant
$DUID_CLIENT = "00:01:00:01:00:04:93:e0:00:00:00:00:a2:a2";
#For Relay agent test;
$NUTRELAY1_LINK0_GLOBAL_UCAST = "3ffe:501:ffff:100:200:ff:fe00:a4a4";
$NUTRELAY1_LINK1_GLOBAL_UCAST = "3ffe:501:ffff:101:200:ff:fe00:a5a5";
$SERVER1_GLOBAL_UCAST = "3ffe:501:ffff:100:200:ff:fe00:a1a1";
#Maximum network interface number
my $MAXIFCOUNT = 1;
#For NUT(server) parameters
my $NUT_Server_Config_ref = undef;
my $NUT_Relay_Config_ref = undef;
#RFC3315 recommanded constants
$SOL_MAX_DELAY = 1;
$SOL_TIMEOUT = 1;
$SOL_MAX_RT = 120;
$REQ_TIMEOUT = 1;
$REQ_MAX_RT = 30;
$REQ_MAX_RC = 10;
$CNF_MAX_DELAY = 1;
$CNF_TIMEOUT = 1;
$CNF_MAX_RT = 4;
$CNF_MAX_RD = 10;
$REN_TIMEOUT = 10;
$REN_MAX_RT = 600;
$REB_TIMEOUT = 10;
$REB_MAX_RT = 600;
$INF_MAX_DELAY = 1;
$INF_TIMEOUT = 1;
$INF_MAX_RT = 120;
$REL_TIMEOUT = 1;
$REL_MAX_RC = 5;
$DEC_TIMEOUT = 1;
$DEC_MAX_RC = 5;
$REC_TIMEOUT = 2;
$REC_MAX_RC = 8;
$RAND = 0.1;
my %option_codes = (
0 => "???",
1 => "OPTION_CLIENTID",
2 => "OPTION_SERVERID",
3 => "OPTION_IA_NA",
4 => "OPTION_IA_TA",
5 => "OPTION_IAADDR",
6 => "OPTION_ORO",
7 => "OPTION_PREFERENCE",
8 => "OPTION_ELAPSED_TIME",
9 => "OPTION_RELAY_MSG",
10 => "???",
11 => "OPTION_AUTH",
12 => "OPTION_UNICAST",
13 => "OPTION_STATUS_CODE",
14 => "OPTION_RAPID_COMMIT",
15 => "OPTION_USER_CLASS",
16 => "OPTION_VENDOR_CLASS",
17 => "OPTION_VENDOR_OPTS",
18 => "OPTION_INTERFACE_ID",
19 => "OPTION_RECONF_MSG",
20 => "OPTION_RECONF_ACCEPT",
21 => "OPTION_SIP_SERVER_D",
22 => "OPTION_SIP_SERVER_A",
23 => "OPTION_DNS_SERVERS",
24 => "OPTION_DOMAIN_LIST",
25 => "OPTION_IA_PD",
26 => "OPTION_IAPREFIX",
31 => "PREFIX_INFORMATION",
32 => "PREFIX_REQUEST"
);
# for compare_options($$$)
$CMP_CID = 1 << 0;
$CMP_SID = 1 << 1;
$CMP_IA_NA = 1 << 2;
$CMP_IA_TA = 1 << 3;
$CMP_IA_ADD = 1 << 4;
$CMP_ORO = 1 << 5;
$CMP_PREF = 1 << 6;
$CMP_ETIME = 1 << 7;
$CMP_RELAYMSG = 1 << 8;
$CMP_AUTH = 1 << 9;
$CMP_SVRUNICAST = 1 << 10;
$CMP_STATUS_CODE = 1 << 11;
$CMP_RAPIDCOMMIT = 1 << 12;
$CMP_USER_CLASS = 1 << 13;
$CMP_VENDER_CLASS = 1 << 14;
$CMP_VENDER_SPEC = 1 << 15;
$CMP_IID = 1 << 16;
$CMP_RECONF_MSG = 1 << 17;
$CMP_RECONF_ACCEPT = 1 << 18;
$CMP_IA_PD = 1 << 19;
$CMP_IA_PREFIX = 1 << 20;
$CMP_DNS_SVR = 1 << 21;
$CMP_DNS_LST = 1 << 22;
$CMP_SIP_D = 1 << 25;
$CMP_SIP_A = 1 << 26;
$CMP_TRANS_ID = 1 << 27;
my %duid_types = (
1=>"DHCPv6_DUID_LLT_Ether",
2=>"DHCPv6_DUID_EN",
3=>"DHCPv6_DUID_LL_Ether"
);
my %option_defs = (
$CMP_CID => "Opt_DHCPv6_CID",
$CMP_SID => "Opt_DHCPv6_SID",
$CMP_IA_NA => "Opt_DHCPv6_IA_NA",
$CMP_IA_TA => "Opt_DHCPv6_IA_TA",
$CMP_IA_ADD => "Opt_DHCPv6_IA_Address",
$CMP_ORO => "Opt_DHCPv6_OptionRequest",
$CMP_PREF => "Opt_DHCPv6_Preference",
$CMP_ETIME => "Opt_DHCPv6_ElapsedTime",
$CMP_RELAYMSG => "Opt_DHCPv6_RelayMessage",
$CMP_AUTH => "Opt_DHCPv6_Authentication",
$CMP_SVRUNICAST => "Opt_DHCPv6_ServerUnicast",
$CMP_STATUS_CODE => "Opt_DHCPv6_StatusCode",
$CMP_RAPIDCOMMIT => "Opt_DHCPv6_RapidCommit",
$CMP_USER_CLASS => "Opt_DHCPv6_UserClass",
$CMP_VENDER_CLASS => "Opt_DHCPv6_VendorClass",
$CMP_VENDER_SPEC => "Opt_DHCPv6_VendorSpecificInfo",
$CMP_IID => "Opt_DHCPv6_IID",
$CMP_RECONF_MSG => "Opt_DHCPv6_ReconfigureMessage",
$CMP_RECONF_ACCEPT => "Opt_DHCPv6_ReconfigureAccept",
$CMP_IA_PD => "Opt_DHCPv6_IA_PD",
$CMP_IA_PREFIX => "Opt_DHCPv6_IA_Prefix",
$CMP_DNS_SVR => "Opt_DHCPv6_DNS_Servers",
$CMP_DNS_LST => "Opt_DHCPv6_DNS_SearchList",
$CMP_SIP_D => "Opt_DHCPv6_SIP_ServerD",
$CMP_SIP_A => "Opt_DHCPv6_SIP_ServerA",
$CMP_TRANS_ID => "Identifier",
);
my %dhcp6_messages = (
"Solicit" => "Frame_Ether.Packet_IPv6.Upp_UDP.Udp_DHCPv6_Solicit",
"Advertise" => "Frame_Ether.Packet_IPv6.Upp_UDP.Udp_DHCPv6_Advertise",
"Request" => "Frame_Ether.Packet_IPv6.Upp_UDP.Udp_DHCPv6_Request",
"Confirm" => "Frame_Ether.Packet_IPv6.Upp_UDP.Udp_DHCPv6_Confirm",
"Reply" => "Frame_Ether.Packet_IPv6.Upp_UDP.Udp_DHCPv6_Reply",
"Renew" => "Frame_Ether.Packet_IPv6.Upp_UDP.Udp_DHCPv6_Renew",
"Rebind" => "Frame_Ether.Packet_IPv6.Upp_UDP.Udp_DHCPv6_Rebind",
"Release" => "Frame_Ether.Packet_IPv6.Upp_UDP.Udp_DHCPv6_Release",
"Decline" => "Frame_Ether.Packet_IPv6.Upp_UDP.Udp_DHCPv6_Decline",
"Reconfigure" => "Frame_Ether.Packet_IPv6.Upp_UDP.Udp_DHCPv6_Reconfigure",
"InformationRequest" => "Frame_Ether.Packet_IPv6.Upp_UDP.Udp_DHCPv6_InformationRequest",
"RelayForward" => "Frame_Ether.Packet_IPv6.Upp_UDP.Udp_DHCPv6_RelayForward",
"RelayReply" => "Frame_Ether.Packet_IPv6.Upp_UDP.Udp_DHCPv6_RelayReply",
);
my %dhcp6_messages_title = (
"Solicit" => "Udp_DHCPv6_Solicit",
"Advertise" => "Udp_DHCPv6_Advertise",
"Request" => "Udp_DHCPv6_Request",
"Confirm" => "Udp_DHCPv6_Confirm",
"Reply" => "Udp_DHCPv6_Reply",
"Renew" => "Udp_DHCPv6_Renew",
"Rebind" => "Udp_DHCPv6_Rebind",
"Release" => "Udp_DHCPv6_Release",
"Decline" => "Udp_DHCPv6_Decline",
"Reconfigure" => "Udp_DHCPv6_Reconfigure",
"InformationRequest" => "Udp_DHCPv6_InformationRequest",
"RelayForward" => "Udp_DHCPv6_RelayForward",
"RelayReply" => "Udp_DHCPv6_RelayReply",
);
my %status_codes = (
0 => "Success",
1 => "UnspecFail",
2 => "NoAddrsAvail",
3 => "NoBinding",
4 => "NotOnLink",
5 => "UseMulticast"
);
#--------------------------------------------------------------------------------------------#
#--------------------------------------------------------------#
# wait_for_dhcp6frame_cpp($if, $timeout, $frame, $cpp) #
# #
# Notes: #
# #
# SUCCESS: return (0, rcv_packet) #
# FAILURE: return (1, ???) #
#--------------------------------------------------------------#
sub wait_for_dhcp6frame_cpp($$$$) {
my ($if, $timeout, $frame, $cpp) = @_;
my $cppstr = "";
#----------------------------#
#print "\n cpp: $cppstr \n";
#----------------------------#
$cppstr .= $cpp;
vCPP($cppstr);
my %ret = vRecvPacket($if, $timeout, 0, 0, $frame);
if ($ret{status} == 0) {
vLogHTML('<B>Got expected Message</B><BR><BR>');
parse_message(\%ret);
return (0, %ret);
}
vLogHTML('<B>Could not get expected Message</B><BR>');
return (1, %ret);
}
#--------------------------------------------------------------#
# wait_for_dhcp6frame($if, $timeout, $frame) #
# #
# Notes: #
# #
# SUCCESS: return (0, rcv_packet) #
# FAILURE: return (1, ???) #
#--------------------------------------------------------------#
sub wait_for_dhcp6frame($$$) {
my ($if, $timeout, $frame) = @_;
my %ret = vRecvPacket($if, $timeout, 0, 0, $frame);
if ($ret{status} == 0) {
vLogHTML('<B>Got Message</B><BR><BR>');
parse_message(\%ret);
return (0, %ret);
}
vLogHTML('<B>Could not get Message</B><BR>');
return (1, %ret);
}
#--------------------------------------------------------------#
# wait_for_solicit($if, $timeout) #
# #
# Notes: #
# #
# SUCCESS: return (0, solicit) #
# FAILURE: return (1, ???) #
#--------------------------------------------------------------#
sub wait_for_solicit($$) {
my ($if, $timeout) = @_;
my $base = "Frame_Ether\.Packet_IPv6\.Upp_UDP\.Udp_DHCPv6_Solicit";
# my %ret = vRecv3($if, $timeout, 0, 0, "dhcp6_solicit");
my %ret = vRecvPacket($if, $timeout, 0, 0, "dhcp6_solicit");
if(defined($ret{"$base"})) {
if ($AUTH_OPTION_REQUIRED){
$ret{'Recv_ReplayDetection'} = $ret{"$base\.Opt_DHCPv6_Authentication\.ReplayDetection"};
}
vLogHTML('<B>got DHCPv6 Solicit Message</B><BR>');
parse_message(\%ret);
if (! defined($ret{"$base\.Opt_DHCPv6_CID"})) {
vLogHTML('<FONT COLOR="#FF0000"><B>Solicit Message MUST include CID option.</B></FONT> see 15.2 Solicit Message(id-28)<BR>');
return (1, %ret);
}
if (defined($ret{"$base\.Opt_DHCPv6_SID"})) {
vLogHTML('<FONT COLOR="#FF0000"><B>Solicit Message MUST NOT include SID option.</B></FONT> see 15.2 Solicit Message(id-28)<BR>');
return (1, %ret);
}
return (0, %ret);
}
vLogHTML('<B>Could not get Solicit Message</B><BR>');
return (1, %ret);
}
#--------------------------------------------------------------#
# wait_for_advertise($if, $timeout) #
# #
# Notes: #
# #
# SUCCESS: return (0, advertise) #
# FAILURE: return (1, ???) #
#--------------------------------------------------------------#
sub wait_for_advertise($$) {
my ($if, $timeout) = @_;
my $base = "Frame_Ether\.Packet_IPv6\.Upp_UDP\.Udp_DHCPv6_Advertise";
my %ret = vRecvPacket($if, $timeout, 0, 0, "dhcp6_advertise");
if(defined($ret{"$base"})) {
if ($AUTH_OPTION_REQUIRED){
$ret{'Recv_ReplayDetection'} = $ret{"$base\.Opt_DHCPv6_Authentication\.ReplayDetection"};
}
vLogHTML('<B>got DHCPv6 Advertise Message</B><BR>');
parse_message(\%ret);
if (! defined($ret{"$base\.Opt_DHCPv6_SID"})) {
vLogHTML('<FONT COLOR="#FF0000"><B>Advertise Message MUST include SID option.</B></FONT> see 15.3 Advertise Message(id-28)<BR>');
return (1, %ret);
}
if (! defined($ret{"$base\.Opt_DHCPv6_CID"})) {
vLogHTML('<FONT COLOR="#FF0000"><B>Advertise Message MUST include CID option.</B></FONT> see 15.3 Advertise Message(id-28)<BR>');
return (1, %ret);
}
return (0, %ret);
}
else{
vLogHTML('<B>Can not got DHCPv6 Advertise Message</B><BR>');
return (1, %ret);
}
}
#--------------------------------------------------------------#
# wait_for_request($if, $timeout) #
# #
# Notes: #
# #
# SUCCESS: return (0, request) #
# FAILURE: return (1, ???) #
#--------------------------------------------------------------#
sub wait_for_request($$) {
my ($if, $timeout) = @_;
my $base = "Frame_Ether\.Packet_IPv6\.Upp_UDP\.Udp_DHCPv6_Request";
# my %ret = vRecv3($if, $timeout, 0, 0, "dhcp6_request");
my %ret = vRecvPacket($if, $timeout, 0, 0, "dhcp6_request");
if($ret{"status"}!= 0){
return ($ret{"status"},%ret);
}
if(defined($ret{"$base"})) {
vLogHTML('<B>got DHCPv6 Request Message</B><BR>');
if ($AUTH_OPTION_REQUIRED){
$ret{'Recv_ReplayDetection'} = $ret{"$base\.Opt_DHCPv6_Authentication\.ReplayDetection"};
}
parse_message(\%ret);
return (0, %ret);
}
vLogHTML('<B>Could not get Request Message</B><BR>');
return (1, %ret);
}
#--------------------------------------------------------------#
# wait_for_confirm($if, $timeout) #
# #
# Notes: #
# #
# SUCCESS: return (0, confirm) #
# FAILURE: return (1, ???) #
#--------------------------------------------------------------#
sub wait_for_confirm($$) {
my ($if, $timeout) = @_;
my $base = "Frame_Ether\.Packet_IPv6\.Upp_UDP\.Udp_DHCPv6_Confirm";
# my %ret = vRecv3($if, $timeout, 0, 0, "dhcp6_confirm");
my %ret = vRecvPacket($if, $timeout, 0, 0, "dhcp6_confirm");
if(defined($ret{"$base"})) {
vLogHTML('<B>got DHCPv6 Confirm Message</B><BR>');
if ($AUTH_OPTION_REQUIRED){
$ret{'Recv_ReplayDetection'} = $ret{"$base\.Opt_DHCPv6_Authentication\.ReplayDetection"};
}
parse_message(\%ret);
if (! defined($ret{"$base\.Opt_DHCPv6_CID"})) {
vLogHTML('<FONT COLOR="#FF0000"><B>Confirm Message MUST include CID option.</B></FONT> see 15.5 Confirm Message(id-28)<BR>');
return (1, %ret);
}
if (defined($ret{"$base\.Opt_DHCPv6_SID"})) {
vLogHTML('<FONT COLOR="#FF0000"><B>Confirm Message MUST NOT include SID option.</B></FONT> see 15.5 Confirm Message(id-28)<BR>');
return (1, %ret);
}
return (0, %ret);
}
vLogHTML('<B>Could not get Confirm Message</B><BR>');
return (1, %ret);
}
#--------------------------------------------------------------#
# wait_for_renew($if, $timeout) #
# #
# Notes: #
# #
# SUCCESS: return (0, renew) #
# FAILURE: return (1, ???) #
#--------------------------------------------------------------#
sub wait_for_renew($$) {
my ($if, $timeout) = @_;
my $base = "Frame_Ether\.Packet_IPv6\.Upp_UDP\.Udp_DHCPv6_Renew";
# my %ret = vRecv3($if, $timeout, 0, 0, "dhcp6_renew");
my %ret = vRecvPacket($if, $timeout, 0, 0, "dhcp6_renew");
if(defined($ret{"$base"})) {
vLogHTML('<B>got DHCPv6 Renew Message</B><BR>');
if ($AUTH_OPTION_REQUIRED){
$ret{'Recv_ReplayDetection'} = $ret{"$base\.Opt_DHCPv6_Authentication\.ReplayDetection"};
}
parse_message(\%ret);
if (! defined($ret{"$base\.Opt_DHCPv6_SID"})) {
vLogHTML('<FONT COLOR="#FF0000"><B>Renew Message MUST include SID option.</B></FONT> see 15.6 Renew Message(id-28)<BR>');
return (1, %ret);
}
if (! defined($ret{"$base\.Opt_DHCPv6_CID"})) {
vLogHTML('<FONT COLOR="#FF0000"><B>Renew Message MUST include CID option.</B></FONT> see 15.6 Renew Message(id-28)<BR>');
return (1, %ret);
}
return (0, %ret);
}
vLogHTML('<B>Could not get Renew Message</B><BR>');
return (1, %ret);
}
#--------------------------------------------------------------#
# wait_for_rebind($if, $timeout) #
# #
# Notes: #
# #
# SUCCESS: return (0, rebind) #
# FAILURE: return (1, ???) #
#--------------------------------------------------------------#
sub wait_for_rebind($$) {
my ($if, $timeout) = @_;
my $base = "Frame_Ether\.Packet_IPv6\.Upp_UDP\.Udp_DHCPv6_Rebind";
# my %ret = vRecv3($if, $timeout, 0, 0, "dhcp6_rebind");
my %ret = vRecvPacket($if, $timeout, 0, 0, "dhcp6_rebind");
if(defined($ret{"$base"})) {
vLogHTML('<B>got DHCPv6 Rebind Message</B><BR>');
if ($AUTH_OPTION_REQUIRED){
$ret{'Recv_ReplayDetection'} = $ret{"$base\.Opt_DHCPv6_Authentication\.ReplayDetection"};
}
parse_message(\%ret);
if (! defined($ret{"$base\.Opt_DHCPv6_CID"})) {
vLogHTML('<FONT COLOR="#FF0000"><B>Rebind Message MUST include CID option.</B></FONT> see 15.7 Rebind Message(id-28)<BR>');
return (1, %ret);
}
if (defined($ret{"$base\.Opt_DHCPv6_SID"})) {
vLogHTML('<FONT COLOR="#FF0000"><B>Rebind Message MUST NOT include SID option.</B></FONT> see 15.7 Rebind Message(id-28)<BR>');
return (1, %ret);
}
return (0, %ret);
}
vLogHTML('<B>Could not get Rebind Message</B><BR>');
return (1, %ret);
}
#--------------------------------------------------------------#
# wait_for_release($if, $timeout) #
# #
# Notes: #
# #
# SUCCESS: return (0, release) #
# FAILURE: return (1, ???) #
#--------------------------------------------------------------#
sub wait_for_release($$) {
my ($if, $timeout) = @_;
my $base = "Frame_Ether\.Packet_IPv6\.Upp_UDP\.Udp_DHCPv6_Release";
# my %ret = vRecv3($if, $timeout, 0, 0, "dhcp6_release");
my %ret = vRecvPacket($if, $timeout, 0, 0, "dhcp6_release");
if($ret{"status"}!= 0){
return ($ret{"status"},%ret);
}
if(defined($ret{"$base"})) {
vLogHTML('<B>got DHCPv6 Release Message</B><BR>');
if ($AUTH_OPTION_REQUIRED){
$ret{'Recv_ReplayDetection'} = $ret{"$base\.Opt_DHCPv6_Authentication\.ReplayDetection"};
}
parse_message(\%ret);
if (! defined($ret{"$base\.Opt_DHCPv6_SID"})) {
vLogHTML('<FONT COLOR="#FF0000"><B>Release Message MUST include SID option.</B></FONT> see 15.9 Release Message(id-28)<BR>');
return (1, %ret);
}
if (! defined($ret{"$base\.Opt_DHCPv6_CID"})) {
vLogHTML('<FONT COLOR="#FF0000"><B>Release Message MUST include CID option.</B></FONT> see 15.9 Release Message(id-28)<BR>');
return (1, %ret);
}
return (0, %ret);
}
vLogHTML('<B>Could not get Release Message</B><BR>');
return (1, %ret);
}
#--------------------------------------------------------------#
# wait_for_reply($if, $timeout) #
# #
# Notes: #
# #
# SUCCESS: return (0, reply) #
# FAILURE: return (1, ???) #
#--------------------------------------------------------------#
sub wait_for_reply($$) {
my ($if, $timeout) = @_;
my $base = "Frame_Ether\.Packet_IPv6\.Upp_UDP\.Udp_DHCPv6_Reply";
my %ret = vRecvPacket($if, $timeout, 0, 0, "dhcp6_reply");
if(defined($ret{"$base"})) {
vLogHTML('<B>got DHCPv6 Reply Message</B><BR>');
if ($AUTH_OPTION_REQUIRED){
$ret{'Recv_ReplayDetection'} = $ret{"$base\.Opt_DHCPv6_Authentication\.ReplayDetection"};
}
parse_message(\%ret);
return (0, %ret);
}
vLogHTML('<B>Could not get Reply Message</B><BR>');
return (1, %ret);
}
#--------------------------------------------------------------#
# wait_for_reconfigure($if, $timeout) #
# #
# Notes: #
# #
# SUCCESS: return (0, reconfigure) #
# FAILURE: return (1, ???) #
#--------------------------------------------------------------#
sub wait_for_reconfigure($$) {
my ($if, $timeout) = @_;
my $base = "Frame_Ether\.Packet_IPv6\.Upp_UDP\.Udp_DHCPv6_Reconfigure";
my %ret = vRecvPacket($if, $timeout, 0, 0, "dhcp6_reconfigure");
if(defined($ret{"$base"})) {
vLogHTML('<B>got DHCPv6 Reconfigure Message</B><BR>');
$ret{'Recv_RecMsgType'} = $ret{"$base\.Opt_DHCPv6_Reconfigure\.Type"};
parse_message(\%ret);
return (0, %ret);
}
vLogHTML('<B>Could not get Reconfigure Message</B><BR>');
return (1, %ret);
}
#--------------------------------------------------------------#
# wait_for_information_request($if, $timeout) #
# #
# Notes: #
# #
# SUCCESS: return (0, information_request) #
# FAILURE: return (1, ???) #
#--------------------------------------------------------------#
sub wait_for_information_request($$) {
my ($if, $timeout) = @_;
my $base = "Frame_Ether\.Packet_IPv6\.Upp_UDP\.Udp_DHCPv6_InformationRequest";
# my %ret = vRecv3($if, $timeout, 0, 0, "dhcp6_information_request");
my %ret = vRecvPacket($if, $timeout, 0, 0, "dhcp6_information_request");
if(defined($ret{"$base"})) {
vLogHTML('<B>got DHCPv6 Information-request Message</B><BR>');
if ($AUTH_OPTION_REQUIRED){
$ret{'Recv_ReplayDetection'} = $ret{"$base\.Opt_DHCPv6_Authentication\.ReplayDetection"};
}
parse_message(\%ret);
return (0, %ret);
}
vLogHTML('<B>Could not get Information-request Message</B><BR>');
return (1, %ret);
}
#--------------------------------------------------------------#
# wait_for_decline($if, $timeout) #
# #
# Notes: #
# #
# SUCCESS: return (0, decline) #
# FAILURE: return (1, ???) #
#--------------------------------------------------------------#
sub wait_for_decline($$) {
my ($if, $timeout) = @_;
my $base = "Frame_Ether\.Packet_IPv6\.Upp_UDP\.Udp_DHCPv6_Decline";
# my %ret = vRecv3($if, $timeout, 0, 0, "dhcp6_decline");
my %ret = vRecvPacket($if, $timeout, 0, 0, "dhcp6_decline");
if(defined($ret{"$base"})) {
vLogHTML('<B>got DHCPv6 Decline Message</B><BR>');
parse_message(\%ret);
return (0, %ret);
}
vLogHTML('<B>Could not get Decline Message</B><BR>');
return (1, %ret);
}
#--------------------------------------------------------------#
# wait_for_relay_forward($if, $maxcount,$strFramename) #
# #
# Notes: #
# #
# SUCCESS: return (0, relay_forward_solicit) #
# FAILURE: return (1, ???) #
#--------------------------------------------------------------#
sub wait_for_relay_forward($$$){
my ($if, $maxcount,$strFramename) = @_;
my $cpp = undef;
my $type=$V6evalTool::NutDef{Type};
if($type eq 'router') {
$cpp .= '-D LINK1';
}
vCPP($cpp);
my $strbase = "Frame_Ether\.Packet_IPv6\.Upp_UDP\.Udp_DHCPv6_RelayForward";
my $retrycount = 0;
for(my $count=0;$count<$maxcount;$count++){
my %ret = vRecvPacket($if, 5, 0, 0,"$strFramename");
if(0 != $ret{"status"} ||(!defined( $ret{$strbase}))){
# dhcpExitError("NG: Can not receive expected Relay Forward Message");
return (1, %ret);
}
elsif( 0 == $ret{"status"}){
parse_relay_message(\%ret);
return (0,%ret);
}
}
}
#--------------------------------------------------------------#
# wait_for_relay_forward_solicit($if, $maxcount) #
# #
# Notes: #
# #
# SUCCESS: return (0, relay_forward_solicit) #
# FAILURE: return (1, ???) #
#--------------------------------------------------------------#
sub wait_for_relay_forward_solicit($$) {
my ($if, $maxcount) = @_;
my $base = "Frame_Ether\.Packet_IPv6\.Upp_UDP\.Udp_DHCPv6_RelayForward\.Opt_DHCPv6_RelayMessage\.Udp_DHCPv6_Solicit";
my $retrycount = 0;
retry:
my %ret = vRecvPacket($if, 5, 0, 0,"relayforward_solicit_nut_to_server1");
if($ret{'status'}){
vLogHTML('<B>Could not get Relay Forward Message(Solicit)</B><BR>');
return (1,%ret);
}
if(defined($ret{"$base"})) {
vLogHTML('<B>got DHCPv6 Relay Forward Message(Solicit)</B><BR>');
parse_relay_message(\%ret);
return (0, %ret);
}
if ($retrycount < $maxcount) {
$retrycount++;
goto retry;
}
vLogHTML('<B>Could not get Relay Forward Message(Solicit)</B><BR>');
return (1, %ret);
}
#--------------------------------------------------------------#
# wait_for_relay_forward_request($if, $maxcount) #
# #
# Notes: #
# #
# SUCCESS: return (0, relay_forward_request) #
# FAILURE: return (1, ???) #
#--------------------------------------------------------------#
sub wait_for_relay_forward_request($$) {
my ($if, $maxcount) = @_;
my $base = "Frame_Ether\.Packet_IPv6\.Upp_UDP\.Udp_DHCPv6_RelayForward\.Opt_DHCPv6_RelayMessage\.Udp_DHCPv6_Request";
my $retrycount = 0;
retry:
my %ret = vRecvPacket($if, 5, 0, 0,"relayforward_request_nut_to_server1");
if(defined($ret{"$base"})) {
vLogHTML('<B>got DHCPv6 Relay Forward Message(Request)</B><BR>');
parse_relay_message(\%ret);
return (0, %ret);
}
if ($retrycount < $maxcount) {
$retrycount++;
goto retry;
}
vLogHTML('<B>Could not get Relay Forward Message(Request)</B><BR>');
return (1, %ret);
}
#--------------------------------------------------------------#
# wait_for_relay_forward_confirm($if, $maxcount) #
# #
# Notes: #
# #
# SUCCESS: return (0, relay_forward_request) #
# FAILURE: return (1, ???) #
#--------------------------------------------------------------#
sub wait_for_relay_forward_confirm($$) {
my ($if, $maxcount) = @_;
my $base = "Frame_Ether\.Packet_IPv6\.Upp_UDP\.Udp_DHCPv6_RelayForward\.Opt_DHCPv6_RelayMessage\.Udp_DHCPv6_Confirm";
my $retrycount = 0;
retry:
my %ret = vRecvPacket($if, 5, 0, 0,"relayforward_confirm_nut_to_server1");
if(defined($ret{"$base"})) {
vLogHTML('<B>got DHCPv6 Relay Forward Message(Confirm)</B><BR>');
parse_relay_message(\%ret);
return (0, %ret);
}
if ($retrycount < $maxcount) {
$retrycount++;
goto retry;
}
vLogHTML('<B>Could not get Relay Forward Message(Confirm)</B><BR>');
return (1, %ret);
}
#--------------------------------------------------------------#
# wait_for_relay_forward_renew($if, $maxcount) #
# #
# Notes: #
# #
# SUCCESS: return (0, relay_forward_request) #
# FAILURE: return (1, ???) #
#--------------------------------------------------------------#
sub wait_for_relay_forward_renew($$) {
my ($if, $maxcount) = @_;
my $base = "Frame_Ether\.Packet_IPv6\.Upp_UDP\.Udp_DHCPv6_RelayForward\.Opt_DHCPv6_RelayMessage\.Udp_DHCPv6_Renew";
my $retrycount = 0;
retry:
my %ret = vRecvPacket($if, 5, 0, 0,"relayforward_renew_nut_to_server1");
if(defined($ret{"$base"})) {
vLogHTML('<B>got DHCPv6 Relay Forward Message(Renew)</B><BR>');
parse_relay_message(\%ret);
return (0, %ret);
}
if ($retrycount < $maxcount) {
$retrycount++;
goto retry;
}
vLogHTML('<B>Could not get Relay Forward Message(Renew)</B><BR>');
return (1, %ret);
}
#--------------------------------------------------------------#
# wait_for_relay_forward_rebind($if, $maxcount) #
# #
# Notes: #
# #
# SUCCESS: return (0, relay_forward_request) #
# FAILURE: return (1, ???) #
#--------------------------------------------------------------#
sub wait_for_relay_forward_rebind($$) {
my ($if, $maxcount) = @_;
my $base = "Frame_Ether\.Packet_IPv6\.Upp_UDP\.Udp_DHCPv6_RelayForward\.Opt_DHCPv6_RelayMessage\.Udp_DHCPv6_Rebind";
my $retrycount = 0;
retry:
my %ret = vRecvPacket($if, 5, 0, 0,"relayforward_rebind_nut_to_server1");
if(defined($ret{"$base"})) {
vLogHTML('<B>got DHCPv6 Relay Forward Message(Rebind)</B><BR>');
parse_relay_message(\%ret);
return (0, %ret);
}
if ($retrycount < $maxcount) {
$retrycount++;
goto retry;
}
vLogHTML('<B>Could not get Relay Forward Message(Rebind)</B><BR>');
return (1, %ret);
}
#--------------------------------------------------------------#
# wait_for_relay_forward_release($if, $maxcount) #
# #
# Notes: #
# #
# SUCCESS: return (0, relay_forward_request) #
# FAILURE: return (1, ???) #
#--------------------------------------------------------------#
sub wait_for_relay_forward_release($$) {
my ($if, $maxcount) = @_;
my $base = "Frame_Ether\.Packet_IPv6\.Upp_UDP\.Udp_DHCPv6_RelayForward\.Opt_DHCPv6_RelayMessage\.Udp_DHCPv6_Release";
my $retrycount = 0;
retry:
my %ret = vRecvPacket($if, 5, 0, 0,"relayforward_release_nut_to_server1");
if(defined($ret{"$base"})) {
vLogHTML('<B>got DHCPv6 Relay Forward Message(Release)</B><BR>');
parse_relay_message(\%ret);
return (0, %ret);
}
if ($retrycount < $maxcount) {
$retrycount++;
goto retry;
}
vLogHTML('<B>Could not get Relay Forward Message(Release)</B><BR>');
return (1, %ret);
}
#--------------------------------------------------------------#
# wait_for_relay_forward_decline($if, $maxcount) #
# #
# Notes: #
# #
# SUCCESS: return (0, relay_forward_request) #
# FAILURE: return (1, ???) #
#--------------------------------------------------------------#
sub wait_for_relay_forward_decline($$) {
my ($if, $maxcount) = @_;
my $base = "Frame_Ether\.Packet_IPv6\.Upp_UDP\.Udp_DHCPv6_RelayForward\.Opt_DHCPv6_RelayMessage\.Udp_DHCPv6_Decline";
my $retrycount = 0;
retry:
my %ret = vRecvPacket($if, 5, 0, 0,"relayforward_decline_nut_to_server1");
if(defined($ret{"$base"})) {
vLogHTML('<B>got DHCPv6 Relay Forward Message(Decline)</B><BR>');
parse_relay_message(\%ret);
return (0, %ret);
}
if ($retrycount < $maxcount) {
$retrycount++;
goto retry;
}
vLogHTML('<B>Could not get Relay Forward Message(Decline)</B><BR>');
return (1, %ret);
}
#--------------------------------------------------------------------#
# wait_for_relay_reply($if, $maxcount,$framename,$mod) #
# Now only support 1 relay agent #
# mod: adv& reply #
#--------------------------------------------------------------------#
sub wait_for_relay_reply($$$$) {
my ($if, $maxcount,$framename,$mod) = @_;
my %replymsgtype = (
"Advertise" => ".Udp_DHCPv6_Advertise",
"Reply" => ".Udp_DHCPv6_Reply",
"Relay" => ".Udp_DHCPv6_RelayReply"
);
$framename = "relay_reply_nut_relay" if(!defined($framename));
my $Relay_reply_base = "Frame_Ether\.Packet_IPv6\.Upp_UDP\.Udp_DHCPv6_RelayReply\.Opt_DHCPv6_RelayMessage";
my %ret = ();
for(my $i=0;$i<$maxcount;$i++){
%ret = vRecvPacket($if, 5, 0, 0,$framename);
if(defined($ret{$Relay_reply_base}) && (0 == $ret{'status'})){
parse_relay_message(\%ret);
if(!defined($replymsgtype{$mod})){
#vLogHTML("<B>The expected message type is $mod</B><BR>");
vLogHTML('<B>The type of message which be relayed is not correct!</B><BR>');
return (1,%ret);
}
my $strIndex = $Relay_reply_base.$replymsgtype{$mod};
DebugStrOut("The Index is $strIndex");
if(defined($ret{$strIndex})){
vLogHTML('<B>Received DHCPv6 Relay Reply Message</B><BR>');
return (0, %ret);
}
}
}
vLogHTML("<B>Could not get expected Relay Reply Message ($mod)</B><BR>");
return (1, %ret);
}
#--------------------------------------------------------------#
# wait_for_relay_reply_advertise($if, $maxcount,$strFrameName) #
# for 1 relay's test case #
# Notes: #
# #
# SUCCESS: return (0, relay_reply_advertise) #
# FAILURE: return (1, ???) #
#--------------------------------------------------------------#
sub wait_for_relay_reply_advertise($$$) {
my ($if, $maxcount,$strFrameName) = @_;
return wait_for_relay_reply($if,$maxcount,$strFrameName,'Advertise');
}
#--------------------------------------------------------------#
# wait_for_relay_reply_reply($if, $maxcount,$strFrameName) #
# #
# Notes: #
# #
# SUCCESS: return (0, relay_reply_reply) #
# FAILURE: return (1, ???) #
#--------------------------------------------------------------#
sub wait_for_relay_reply_reply($$;$) {
my ($if, $maxcount,$strFrameName) = @_;
return wait_for_relay_reply($if,$maxcount,$strFrameName,'Reply');
}
#--------------------------------------------------------------#
# wait_for_relay_reply_relay($if, $maxcount) #
# #
# Notes: #
# #
# SUCCESS: return (0, relay_reply_relay) #
# FAILURE: return (1, ???) #
#--------------------------------------------------------------#
sub wait_for_relay_reply_relay($$$) {
my ($if, $maxcount,$strFrameName) = @_;
return wait_for_relay_reply($if,$maxcount,$strFrameName,'Relay');
}
#--------------------------------------------------------------#
# sub send_relay_reply($if,$relay_reply,$solicit,$cpp) #
# #
#Notes: #
# Send relay-reply message to the relay agent #
# Success: return (0, relay-reply); #
# Fail: return (1,????); #
#--------------------------------------------------------------#
sub send_relay_reply($$$$){
my ($if,$relay_reply,$solicit,$cpp) = @_;
$cpp = defined($cpp) ? $cpp : '';
#if NUT sends IID option, TN copes it.
if( 0 ==options_exist($solicit,$CMP_IID)){
$cpp .= '-D INSERT_IID=1';
my $ID = $$solicit{"Frame_Ether.Packet_IPv6.Upp_UDP.Udp_DHCPv6_RelayForward.Opt_DHCPv6_IID.Identifier"};
$cpp .= " -D\'IID_IDENTIFIER=$ID\' ";
}
createPacketDefinitionFile("DHCPv6_test.def");
$cpp .= MakeCppForReplyMessage($solicit,".Udp_DHCPv6_RelayForward.Opt_DHCPv6_RelayMessage");
my $type=$V6evalTool::NutDef{Type};
if($type eq 'router') {
$cpp .= '-D LINK1';
}
vCPP($cpp);
#printf("cpp is $cpp<BR>");
my %ret = vSend3($if,$relay_reply);
parse_relay_message(\%ret);
return (0,%ret);
}
#--------------------------------------------------------------#
# send_solicit($if, $solicit, $cpp) #
# #
# Notes: #
# make Solicit Message #
# SUCCESS: return (0, solicit) #
# FAILURE: return (1, ???) #
#--------------------------------------------------------------#
sub send_solicit($$$) {
my ($if, $solicit, $cpp) = @_;
$cpp = defined($cpp) ? $cpp : '';
createPacketDefinitionFile("DHCPv6_test.def");
vCPP($cpp);
my %ret = vSend3($if, $solicit);
parse_message(\%ret);
return (0, %ret) if(0 == $ret{status});
return (1, %ret);
}
#--------------------------------------------------------------#
# send_advertise($if, $advertise, $solicit, $cpp) #
# #
# Notes: #
# make Advertise Message by using received Solicit #
# SUCCESS: return (0, advertise) #
# FAILURE: return (1, ???) #
#--------------------------------------------------------------#
sub send_advertise($$$$) {
my ($if, $advertise, $solicit, $cpp) = @_;
$cpp = defined($cpp) ? $cpp : '';
my $base = "Frame_Ether.Packet_IPv6.Upp_UDP.Udp_DHCPv6_Solicit";
my $optstr = "";
my $cppstr = "";
# make packet definition
#
#
#
$cppstr .= SetCidOption($solicit, $base);
print "**********************************\n";
print "cppstr = $cppstr \n";
print "**********************************\n";
# if(defined($$solicit{"$base.Opt_DHCPv6_CID.DHCPv6_DUID_LLT_Ether.LinkLayerAddress"}))
# {
# $optstr = $$solicit{"$base.Opt_DHCPv6_CID.DHCPv6_DUID_LLT_Ether.LinkLayerAddress"};
# $cppstr .= " -D\'NUT_DUID_MAC_ADDR=ether(\"$optstr\")\' ";
# }
# if(defined($$solicit{"$base.Opt_DHCPv6_CID.DHCPv6_DUID_LLT_Ether.Time"}))
# {
# $optstr = $$solicit{"$base.Opt_DHCPv6_CID.DHCPv6_DUID_LLT_Ether.Time"};
# $cppstr .= " -D\'NUT_DUID_TIME=$optstr\' ";
# }
# when receive DUID Code =1 and Hareware type is not 1
# if(defined($$solicit{"$base.Opt_DHCPv6_CID.DHCPv6_DUID_LLT_ANY.HardwareType"}))
# {
# $optstr = $$solicit{"$base.Opt_DHCPv6_CID.DHCPv6_DUID_LLT_ANY.HardwareType"};
# $cppstr .= " -D\'NUT_DUID_HARDWARE_TYPE = $optstr\' ";
# }
# if(defined($$solicit{"$base.Opt_DHCPv6_CID.DHCPv6_DUID_LLT_ANY.LinkLayerAddress"}))
# {
# $optstr = $$solicit{"$base.Opt_DHCPv6_CID.DHCPv6_DUID_LLT_ANY.LinkLayerAddress"};
# $cppstr .= " -D\'NUT_DUID_MAC_ADDR=hexstr(\"$optstr\")\' ";
# }
# if(defined($$solicit{"$base.Opt_DHCPv6_CID.DHCPv6_DUID_LLT_ANY.Time"}))
# {
# $optstr = $$solicit{"$base.Opt_DHCPv6_CID.DHCPv6_DUID_LLT_ANY.Time"};
# $cppstr .= " -D\'NUT_DUID_TIME=$optstr\' ";
# }
if(defined($$solicit{"$base.Identifier"}))
{
$optstr = $$solicit{"$base.Identifier"};
$cppstr .= " -D\'ID_ADV=$optstr\' ";
}
# set IA Options
if(defined($$solicit{"$base.Opt_DHCPv6_IA_NA.Identifier"}))
{
$optstr = $$solicit{"$base.Opt_DHCPv6_IA_NA.Identifier"};
$cppstr .= " -D\'IA_NA_IDENTIFIER=$optstr\' ";
}
if(defined($$solicit{"$base.Opt_DHCPv6_IA_TA.Identifier"}))
{
$optstr = $$solicit{"$base.Opt_DHCPv6_IA_TA.Identifier"};
$cppstr .= " -D\'IA_TA_IDENTIFIER=$optstr\' ";
}
if(defined($$solicit{"$base.Opt_DHCPv6_IA_PD.Identifier"}))
{
$optstr = $$solicit{"$base.Opt_DHCPv6_IA_PD.Identifier"};
$cppstr .= " -D\'IA_PD_IDENTIFIER=$optstr\' ";
}
createPacketDefinitionFile("DHCPv6_test.def");
print "\n cpp: $cppstr \n";
$cppstr .= $cpp;
vCPP($cppstr);
# send DHCPv6 Advertise Message
my %ret = vSend3($if, $advertise);
parse_message(\%ret);
return (0, %ret) if(0 == $ret{status});
return (1, %ret);
}
sub send_advertise1($$$$) {
my ($if, $advertise, $solicit, $cpp) = @_;
$cpp = defined($cpp) ? $cpp : '';
my $base = "Frame_Ether.Packet_IPv6.Upp_UDP.Udp_DHCPv6_Solicit";
my $optstr = "";
my $cppstr = "";
if(defined($$solicit{"$base.Opt_DHCPv6_CID.DHCPv6_DUID_LLT_Ether.LinkLayerAddress"}))
{
$optstr = $$solicit{"$base.Opt_DHCPv6_CID.DHCPv6_DUID_LLT_Ether.LinkLayerAddress"};
$cppstr .= " -D\'NUT_DUID_MAC_ADDR=ether(\"$optstr\")\' ";
}
if(defined($$solicit{"$base.Opt_DHCPv6_CID.DHCPv6_DUID_LLT_Ether.Time"}))
{
$optstr = $$solicit{"$base.Opt_DHCPv6_CID.DHCPv6_DUID_LLT_Ether.Time"};
$cppstr .= " -D\'NUT_DUID_TIME=$optstr\' ";
}
# when receive DUID Code =1 and Hareware type is not 1
if(defined($$solicit{"$base.Opt_DHCPv6_CID.DHCPv6_DUID_LLT_ANY.HardwareType"}))
{
$optstr = $$solicit{"$base.Opt_DHCPv6_CID.DHCPv6_DUID_LLT_ANY.HardwareType"};
$cppstr .= " -D\'NUT_DUID_HARDWARE_TYPE = $optstr\' ";
}
if(defined($$solicit{"$base.Opt_DHCPv6_CID.DHCPv6_DUID_LLT_ANY.LinkLayerAddress"}))
{
$optstr = $$solicit{"$base.Opt_DHCPv6_CID.DHCPv6_DUID_LLT_ANY.LinkLayerAddress"};
$cppstr .= " -D\'NUT_DUID_MAC_ADDR=hexstr(\"$optstr\")\' ";
}
if(defined($$solicit{"$base.Opt_DHCPv6_CID.DHCPv6_DUID_LLT_ANY.Time"}))
{
$optstr = $$solicit{"$base.Opt_DHCPv6_CID.DHCPv6_DUID_LLT_ANY.Time"};
$cppstr .= " -D\'NUT_DUID_TIME=$optstr\' ";
}
if(defined($$solicit{"$base.Identifier"}))
{
$optstr = $$solicit{"$base.Identifier"};
$cppstr .= " -D\'ID_ADV=$optstr\' ";
}
# set IA Options
if(defined($$solicit{"$base.Opt_DHCPv6_IA_NA.Identifier"}))
{
$optstr = $$solicit{"$base.Opt_DHCPv6_IA_NA.Identifier"};
$cppstr .= " -D\'IA_NA_IDENTIFIER=$optstr\' ";
}
if(defined($$solicit{"$base.Opt_DHCPv6_IA_TA.Identifier"}))
{
$optstr = $$solicit{"$base.Opt_DHCPv6_IA_TA.Identifier"};
$cppstr .= " -D\'IA_TA_IDENTIFIER=$optstr\' ";
}
if(defined($$solicit{"$base.Opt_DHCPv6_IA_PD.Identifier"}))
{
$optstr = $$solicit{"$base.Opt_DHCPv6_IA_PD.Identifier"};
$cppstr .= " -D\'IA_PD_IDENTIFIER=$optstr\' ";
}
createPacketDefinitionFile("DHCPv6_test.def");
print "\n cpp: $cppstr \n";
$cppstr .= $cpp;
vCPP($cppstr);
# send DHCPv6 Advertise Message
my %ret = vSend3($if, $advertise);
parse_message(\%ret);
return (0, %ret) if(0 == $ret{status});
return (1, %ret);
}
#--------------------------------------------------------------#
# send_advertise2($if, $advertise, $solicit, $cpp) #
# #
# Notes: #
# make Advertise Message by using received Solicit #
# SUCCESS: return (0, advertise) #
# FAILURE: return (1, ???) #
#--------------------------------------------------------------#
sub send_advertise2($$$$) {
my ($if, $advertise, $solicit, $cpp) = @_;
$cpp = defined($cpp) ? $cpp : '';
my $base = "Frame_Ether.Packet_IPv6.Upp_UDP.Udp_DHCPv6_Solicit";
my $optstr = "";
my $cppstr = "";
# make packet definition
# if(defined($$solicit{"$base.Opt_DHCPv6_CID.DHCPv6_DUID_LLT_Ether.LinkLayerAddress"}))
# {
# $optstr = $$solicit{"$base.Opt_DHCPv6_CID.DHCPv6_DUID_LLT_Ether.LinkLayerAddress"};
# $cppstr .= " -D\'NUT_DUID_MAC_ADDR=ether(\"$optstr\")\' ";
# }
# if(defined($$solicit{"$base.Opt_DHCPv6_CID.DHCPv6_DUID_LLT_Ether.Time"}))
# {
# $optstr = $$solicit{"$base.Opt_DHCPv6_CID.DHCPv6_DUID_LLT_Ether.Time"};
# $cppstr .= " -D\'NUT_DUID_TIME=$optstr\' ";
# }
# when receive DUID Code =1 and Hareware type is not 1
# if(defined($$solicit{"$base.Opt_DHCPv6_CID.DHCPv6_DUID_LLT_ANY.HardwareType"}))
# {
# $optstr = $$solicit{"$base.Opt_DHCPv6_CID.DHCPv6_DUID_LLT_ANY.HardwareType"};
# $cppstr .= " -D\'NUT_DUID_HARDWARE_TYPE = $optstr\' ";
# }
# if(defined($$solicit{"$base.Opt_DHCPv6_CID.DHCPv6_DUID_LLT_ANY.LinkLayerAddress"}))
# {
# $optstr = $$solicit{"$base.Opt_DHCPv6_CID.DHCPv6_DUID_LLT_ANY.LinkLayerAddress"};
# $cppstr .= " -D\'NUT_DUID_MAC_ADDR=hexstr(\"$optstr\")\' ";
# }
# if(defined($$solicit{"$base.Opt_DHCPv6_CID.DHCPv6_DUID_LLT_ANY.Time"}))
# {
# $optstr = $$solicit{"$base.Opt_DHCPv6_CID.DHCPv6_DUID_LLT_ANY.Time"};
# $cppstr .= " -D\'NUT_DUID_TIME=$optstr\' ";
# }
$cppstr .= SetCidOption($solicit, $base);
if(defined($$solicit{"$base.Identifier"}))
{
$optstr = $$solicit{"$base.Identifier"};
$cppstr .= " -D\'ID_ADV=$optstr\' ";
}
# set IA Options
if(defined($$solicit{"$base.Opt_DHCPv6_IA_NA.Identifier"}))
{
$optstr = $$solicit{"$base.Opt_DHCPv6_IA_NA.Identifier"};
$cppstr .= " -D\'IA_NA_IDENTIFIER_1=$optstr\' "
}
if(defined($$solicit{"$base.Opt_DHCPv6_IA_TA.Identifier"}))
{
$optstr = $$solicit{"$base.Opt_DHCPv6_IA_TA.Identifier"};
$cppstr .= " -D\'IA_TA_IDENTIFIER=$optstr\' ";
}
if(defined($$solicit{"$base.Opt_DHCPv6_IA_PD.Identifier"}))
{
$optstr = $$solicit{"$base.Opt_DHCPv6_IA_PD.Identifier"};
$cppstr .= " -D\'IA_PD_IDENTIFIER=$optstr\' ";
}
if(defined($$solicit{"$base.Opt_DHCPv6_IA_PD2.Identifier"}))
{
$optstr = $$solicit{"$base.Opt_DHCPv6_IA_PD2.Identifier"};
$cppstr .= " -D\'IA_PD_IDENTIFIER_2=$optstr\' ";
}
if(defined($$solicit{"$base.Opt_DHCPv6_IA_NA2.Identifier"}))
{
$optstr = $$solicit{"$base.Opt_DHCPv6_IA_NA2.Identifier"};
$cppstr .= " -D\'IA_NA_IDENTIFIER_2=$optstr\' "
}
createPacketDefinitionFile("DHCPv6_test.def");
# print "\n cpp: $cppstr \n";
$cppstr .= $cpp;
vCPP($cppstr);
# send DHCPv6 Advertise Message
my %ret = vSend3($if, $advertise);
parse_message(\%ret);
return (0, %ret) if(0 == $ret{status});
return (1, %ret);
}
#--------------------------------------------------------------#
# GetSvrDUIDfromPreMsg( $ref_mag, $base) #
# #
# Notes: #
# make $cpp for DUID from last message #
# SUCCESS: return (0, $cpp) #
# FAILURE: return (1, ???) #
#--------------------------------------------------------------#
sub GetSvrDUIDfromPreMsg($$){
my ($ref_msg,$base) = @_;
my %DUIDTYPE = ("DHCPv6_DUID_LLT_Ether"=>1,
"DHCPv6_DUID_EN"=>2,
"DHCPv6_DUID_LL_Ether"=>3
);
my $duidtype = undef;
my $duidindexname = undef;
my $cpp = undef;
foreach (keys %DUIDTYPE) {
if(defined($$ref_msg{"$base.Opt_DHCPv6_SID.$_"})){
$duidindexname = $base.".Opt_DHCPv6_SID.".$_;
$duidtype = $DUIDTYPE{$_};
last;
}
}
#vLogHTML("index str is $duidindexname<BR>" );
my $hexData = undef;
if(defined($duidtype)){
if(1 == $duidtype || 3 == $duidtype){
my $hardwaretype = $$ref_msg{"$duidindexname.HardwareType"};
my $time = $$ref_msg{"$duidindexname.Time"};
my $linkerlayeraddress = $$ref_msg{"$duidindexname.LinkLayerAddress"};
$linkerlayeraddress =~ s/://g;
my $endofaddress = $$ref_msg{"$duidindexname.[Needless].data"};
if(defined($endofaddress)){
$linkerlayeraddress .= $endofaddress;
}
if(1 == $duidtype){
$hexData = sprintf("%04x%08x",$hardwaretype,$time);
$hexData .= $linkerlayeraddress;
$cpp = " -D\'DUIDANY_SID_TYPE=1\' ";
}
else{
$hexData = sprintf("%04x",$hardwaretype);
$hexData .= $linkerlayeraddress;
$cpp = " -D\'DUIDANY_SID_TYPE=3\' ";
}
if( (!defined($hardwaretype)) || (!defined($linkerlayeraddress))){
vLogHTML("The format of DUID is wrong!<BR>");
vLogHTML("Hardware type: $hardwaretype<BR>");
vLogHTML("linkerlayeraddress is $linkerlayeraddress<BR>");
vLogHTML("hexData is $hexData<BR>");
return (1,$cpp);
}
if((!defined($time)) && (3 == $duidtype)){
vLogHTML("The format of DUID is wrong!<BR>");
vLogHTML("time is $time<BR>");
vLogHTML("hexData is $hexData<BR>");
return (1,$cpp);
}
$cpp .= " -D\'DUIDANY_SID_DATA=hexstr(\"$hexData\")\' ";
}
elsif( 2 == $duidtype){
my $enterprisenumber = $$ref_msg{"$duidindexname.EnterpriseNumber"};
my $id = $$ref_msg{"$duidindexname.Identifier"};
my $endofid = $$ref_msg{"$duidindexname.[Needless].data"};
if(defined($endofid)){
$id .= $endofid;
}
$cpp = " -D\'DUIDANY_SID_TYPE=2\' ";
$hexData = sprintf("%08x",$enterprisenumber);
$hexData .= $id;
if( (!defined($enterprisenumber)) || (!defined($id ))){
vLogHTML("The format of DUID is wrong!<BR>");
vLogHTML("Enterprisenumber: $enterprisenumber<BR>");
vLogHTML("ID is $id<BR>");
vLogHTML("hexData is $hexData<BR>");
return (1,$cpp);
}
$cpp .= " -D\'DUIDANY_SID_DATA=hexstr(\"$hexData\")\' ";
}
}
else{
# vLogHTML("Can not found DUID in this message<BR>");
return (1,$cpp);
}
#vLogHTML("The value of cpp is $cpp<BR>");
return (0,$cpp);
}
#--------------------------------------------------------------#
# send_request($if, $request, $advertise, $cpp) #
# #
# Notes: #
# make Request Message by using received Advertisement #
# SUCCESS: return (0, request) #
# FAILURE: return (1, ???) #
#--------------------------------------------------------------#
sub send_request($$$$) {
my ($if, $request, $advertise, $cpp) = @_;
$cpp = defined($cpp) ? $cpp : '';
my $base = "Frame_Ether.Packet_IPv6.Upp_UDP.Udp_DHCPv6_Advertise";
my $optstr = "";
my ($ret,$cpp_cp) = GetSvrDUIDfromPreMsg($advertise,$base);
$cpp .= $cpp_cp;
if(defined($$advertise{"$base.Opt_DHCPv6_IA_NA.Opt_DHCPv6_IA_Address.Address"}))
{
$optstr = $$advertise{"$base.Opt_DHCPv6_IA_NA.Opt_DHCPv6_IA_Address.Address"};
$cpp .= " -D\'IA_ADDR_ADDR=v6(\"$optstr\")\' ";
}
#In a message
# sent by a delegating router to a requesting router, the requesting
# router MUST use the values in the T1 and T2 fields for the T1 and T2
# parameters. The values in the T1 and T2 fields are the number of
# seconds until T1 and T2.
if(defined($$advertise{"$base.Opt_DHCPv6_IA_PD"}))
{
$optstr = $$advertise{"$base.Opt_DHCPv6_IA_PD.Time1"};
$cpp .= " -D\'IA_PD_TIME1=$optstr\' " if $optstr;
$optstr = $$advertise{"$base.Opt_DHCPv6_IA_PD.Time2"};
$cpp .= " -D\'IA_PD_TIME2=$optstr\' " if $optstr;
}
createPacketDefinitionFile("DHCPv6_test.def");
vCPP($cpp);
# send DHCPv6 Request Message
my %ret = vSend3($if, $request);
parse_message(\%ret);
return (0, %ret) if(0 == $ret{status});
return (1, %ret);
}
#--------------------------------------------------------------#
# send_confirm($if, $confirm, $reply, $cpp) #
# #
# Notes: #
# make Confirm Message by using received Reply #
# SUCCESS: return (0, confirm) #
# FAILURE: return (1, ???) #
#--------------------------------------------------------------#
sub send_confirm($$$$) {
my ($if, $confirm, $reply, $cpp) = @_;
$cpp = defined($cpp) ? $cpp : '';
my $base = "Frame_Ether.Packet_IPv6.Upp_UDP.Udp_DHCPv6_Reply";
my $optstr = "";
# make packet definition
#$SID_OPTION = undef;
#Comment: the SID Must not in Confrim message!!!
if(defined($SID_OPTION)){
my ($ret,$cpp_cp) = GetSvrDUIDfromPreMsg($reply,$base);
$cpp .= $cpp_cp;
}
if(defined($$reply{"$base.Opt_DHCPv6_IA_NA.Opt_DHCPv6_IA_Address.Address"}))
{
$optstr = $$reply{"$base.Opt_DHCPv6_IA_NA.Opt_DHCPv6_IA_Address.Address"};
$cpp .= " -D\'IA_ADDR_ADDR=v6(\"$optstr\")\' ";
} elsif (defined($$reply{"$base.Opt_DHCPv6_IA_TA.Opt_DHCPv6_IA_Address.Address"})) {
$optstr = $$reply{"$base.Opt_DHCPv6_IA_TA.Opt_DHCPv6_IA_Address.Address"};
$cpp .= " -D\'IA_ADDR_ADDR=v6(\"$optstr\")\' ";
}
createPacketDefinitionFile("DHCPv6_test.def");
#default value is 0;
$cpp .= " -D\'IA_ADDR_PLTIME=0\' -D\'IA_ADDR_VLTIME=0\' ";
$cpp .= " -D\'IA_NA_TIME1=0\' -D\'IA_NA_TIME2=0\' ";
vCPP($cpp);
# send DHCPv6 Confirm Message
my %ret = vSend3($if, $confirm);
parse_message(\%ret);
return (0, %ret) if(0 == $ret{status});
return (1, %ret);
}
#--------------------------------------------------------------#
# send_renew($if, $renew, $reply, $cpp) #
# #
# Notes: #
# make Renew Message by using received Reply #
# SUCCESS: return (0, renew) #
# FAILURE: return (1, ???) #
#--------------------------------------------------------------#
sub send_renew($$$$) {
my ($if, $renew, $reply, $cpp) = @_;
$cpp = defined($cpp) ? $cpp : '';
my $base = "Frame_Ether.Packet_IPv6.Upp_UDP.Udp_DHCPv6_Reply";
my $optstr = "";
# make packet definition
my ($ret,$cpp_cp) = GetSvrDUIDfromPreMsg($reply,$base);
$cpp .= $cpp_cp;
#add by haoda 8/31
if(defined($$reply{"$base.Opt_DHCPv6_IA_NA.Opt_DHCPv6_IA_Address.Address"})){
$optstr = $$reply{"$base.Opt_DHCPv6_IA_NA.Opt_DHCPv6_IA_Address.Address"};
$cpp .= " -D\'IA_ADDR_ADDR=v6(\"$optstr\")\' ";
}
elsif (defined($$reply{"$base.Opt_DHCPv6_IA_TA.Opt_DHCPv6_IA_Address.Address"})) {
$optstr = $$reply{"$base.Opt_DHCPv6_IA_TA.Opt_DHCPv6_IA_Address.Address"};
$cpp .= " -D\'IA_ADDR_ADDR=v6(\"$optstr\")\' ";
}
#add by haoda .....8/31
createPacketDefinitionFile("DHCPv6_test.def");
vCPP($cpp);
# send DHCPv6 Renew Message
my %ret = vSend3($if, $renew);
parse_message(\%ret);
return (0, %ret) if(0 == $ret{status});
return (1, %ret);
}
#--------------------------------------------------------------#
# send_rebind($if, $rebind, $reply, $cpp) #
# #
# Notes: #
# make Rebind Message by using received Reply #
# SUCCESS: return (0, rebind) #
# FAILURE: return (1, ???) #
#--------------------------------------------------------------#
sub send_rebind($$$$) {
my ($if, $rebind, $reply, $cpp) = @_;
$cpp = defined($cpp) ? $cpp : '';
my $base = "Frame_Ether.Packet_IPv6.Upp_UDP.Udp_DHCPv6_Reply";
my $optstr = "";
# make packet definition
if(defined($SID_OPTION)){
my ($ret,$cpp_cp) = GetSvrDUIDfromPreMsg($reply,$base);
$cpp .= $cpp_cp;
}
if (0 > index($cpp, "IA_ADDR_ADDR")) {
if(defined($$reply{"$base.Opt_DHCPv6_IA_NA.Opt_DHCPv6_IA_Address.Address"}))
{
$optstr = $$reply{"$base.Opt_DHCPv6_IA_NA.Opt_DHCPv6_IA_Address.Address"};
$cpp .= " -D\'IA_ADDR_ADDR=v6(\"$optstr\")\' ";
} elsif (defined($$reply{"$base.Opt_DHCPv6_IA_TA.Opt_DHCPv6_IA_Address.Address"})) {
$optstr = $$reply{"$base.Opt_DHCPv6_IA_TA.Opt_DHCPv6_IA_Address.Address"};
$cpp .= " -D\'IA_ADDR_ADDR=v6(\"$optstr\")\' ";
}
}
$cpp .= " -D\'IA_ADDR_PLTIME=7000\' -D\'IA_ADDR_VLTIME=11000\' ";
createPacketDefinitionFile("DHCPv6_test.def");
vCPP($cpp);
# send DHCPv6 Rebind Message
my %ret = vSend3($if, $rebind);
if(defined($ret{"Frame_Ether\.Packet_IPv6\.Upp_UDP\.Udp_DHCPv6_Rebind"})) {
parse_message(\%ret);
return (0, %ret) if(0 == $ret{status});
}
return (1, %ret);
}
#--------------------------------------------------------------#
# send_decline($if, $decline, $reply, $cpp) #
# #
# Notes: #
# make Decline Message by using received Reply #
# SUCCESS: return (0, decline) #
# FAILURE: return (1, ???) #
#--------------------------------------------------------------#
sub send_decline($$$$) {
my ($if, $decline, $reply, $cpp) = @_;
$cpp = defined($cpp) ? $cpp : '';
my $base = "Frame_Ether.Packet_IPv6.Upp_UDP.Udp_DHCPv6_Reply";
my $optstr = "";
# make packet definition
my ($ret,$cpp_cp) = GetSvrDUIDfromPreMsg($reply,$base);
$cpp .= $cpp_cp;
if(defined($$reply{"$base.Opt_DHCPv6_IA_NA.Opt_DHCPv6_IA_Address"}))
{
$optstr = $$reply{"$base.Opt_DHCPv6_IA_NA.Opt_DHCPv6_IA_Address.PreferredLifetime"};
$cpp .= " -D\'IA_ADDR_PLTIME=$optstr\' ";
$optstr = $$reply{"$base.Opt_DHCPv6_IA_NA.Opt_DHCPv6_IA_Address.ValidLifetime"};
$cpp .= " -D\'IA_ADDR_VLTIME=$optstr\' ";
}
if (0 > index($cpp, "IA_ADDR_ADDR")) {
if(defined($$reply{"$base.Opt_DHCPv6_IA_NA.Opt_DHCPv6_IA_Address.Address"}))
{
$optstr = $$reply{"$base.Opt_DHCPv6_IA_NA.Opt_DHCPv6_IA_Address.Address"};
$cpp .= " -D\'IA_ADDR_ADDR=v6(\"$optstr\")\' ";
} elsif (defined($$reply{"$base.Opt_DHCPv6_IA_TA.Opt_DHCPv6_IA_Address.Address"})) {
$optstr = $$reply{"$base.Opt_DHCPv6_IA_TA.Opt_DHCPv6_IA_Address.Address"};
$cpp .= " -D\'IA_ADDR_ADDR=v6(\"$optstr\")\' ";
}
}
createPacketDefinitionFile("DHCPv6_test.def");
vCPP($cpp);
# send DHCPv6 Decline Message
my %ret = vSend3($if, $decline);
if(defined($ret{"Frame_Ether\.Packet_IPv6\.Upp_UDP\.Udp_DHCPv6_Decline"})) {
parse_message(\%ret);
return (0, %ret) if(0 == $ret{status});
}
return (1, %ret);
}
#--------------------------------------------------------------#
# send_release($if, $release, $reply, $cpp) #
# #
# Notes: #
# make Release Message by using received Reply #
# SUCCESS: return (0, release) #
# FAILURE: return (1, ???) #
#--------------------------------------------------------------#
sub send_release($$$$) {
my ($if, $release, $reply, $cpp) = @_;
$cpp = defined($cpp) ? $cpp : '';
my $base = "Frame_Ether.Packet_IPv6.Upp_UDP.Udp_DHCPv6_Reply";
my $optstr = "";
# make packet definition
my ($ret,$cpp_cp) = GetSvrDUIDfromPreMsg($reply,$base);
$cpp .= $cpp_cp;
if(defined($$reply{"$base.Opt_DHCPv6_IA_NA.Opt_DHCPv6_IA_Address"}))
{
$optstr = $$reply{"$base.Opt_DHCPv6_IA_NA.Opt_DHCPv6_IA_Address.PreferredLifetime"};
$cpp .= " -D\'IA_ADDR_PLTIME=$optstr\' ";
$optstr = $$reply{"$base.Opt_DHCPv6_IA_NA.Opt_DHCPv6_IA_Address.ValidLifetime"};
$cpp .= " -D\'IA_ADDR_VLTIME=$optstr\' ";
}
if (0 > index($cpp, "IA_ADDR_ADDR")) {
if(defined($$reply{"$base.Opt_DHCPv6_IA_NA.Opt_DHCPv6_IA_Address.Address"}))
{
$optstr = $$reply{"$base.Opt_DHCPv6_IA_NA.Opt_DHCPv6_IA_Address.Address"};
$cpp .= " -D\'IA_ADDR_ADDR=v6(\"$optstr\")\' ";
} elsif (defined($$reply{"$base.Opt_DHCPv6_IA_TA.Opt_DHCPv6_IA_Address.Address"})) {
$optstr = $$reply{"$base.Opt_DHCPv6_IA_TA.Opt_DHCPv6_IA_Address.Address"};
$cpp .= " -D\'IA_ADDR_ADDR=v6(\"$optstr\")\' ";
}
}
createPacketDefinitionFile("DHCPv6_test.def");
vCPP($cpp);
# send DHCPv6 Release Message
my %ret = vSend3($if, $release);
if(defined($ret{"Frame_Ether\.Packet_IPv6\.Upp_UDP\.Udp_DHCPv6_Release"})) {
parse_message(\%ret);
return (0, %ret) if(0 == $ret{status});
}
return (1, %ret);
}
#--------------------------------------------------------------#
# SetCidOption($frame, $base) #
# #
# Notes: #
# According to original message set CID opiton. #
# #
# IN: #
# $frame #
# $base #
# #
# OUT: #
# $cppstr #
# #
#--------------------------------------------------------------#
sub SetCidOption($$){
my ($frame, $base) = @_;
my $optstr = "";
my $cppstr = "";
# DUID LLT, Hardware Type = 1
if(defined($$frame{"$base.Opt_DHCPv6_CID.DHCPv6_DUID_LLT_Ether.Type"}))
{
$CID_OPTION = "opt_CID_LLT_nut";
$optstr = $$frame{"$base.Opt_DHCPv6_CID.DHCPv6_DUID_LLT_Ether.Time"};
$cppstr .= " -D\'NUT_DUID_TIME=$optstr\' ";
$optstr = $$frame{"$base.Opt_DHCPv6_CID.DHCPv6_DUID_LLT_Ether.LinkLayerAddress"};
$cppstr .= " -D\'NUT_DUID_MAC_ADDR=ether(\"$optstr\")\' ";
}
#DUID LLT, Hardware Type = other than 1
if(defined($$frame{"$base.Opt_DHCPv6_CID.DHCPv6_DUID_LLT_ANY.Type"}))
{
$CID_OPTION = "opt_CID_LLT_nut";
$optstr = $$frame{"$base.Opt_DHCPv6_CID.DHCPv6_DUID_LLT_ANY.HardwareType"};
$cppstr .= " -D\'NUT_DUID_HARDWARE_TYPE = $optstr\'";
$optstr = $$frame{"$base.Opt_DHCPv6_CID.DHCPv6_DUID_LLT_ANY.Time"};
$cppstr .= " -D\'NUT_DUID_TIME=$optstr\' ";
$optstr = $$frame{"$base.Opt_DHCPv6_CID.DHCPv6_DUID_LLT_ANY.LinkLayerAddress"};
$cppstr .= " -D\'NUT_DUID_MAC_ADDR=hexstr(\"$optstr\")\'";
}
#DUID EN
if(defined($$frame{"$base.Opt_DHCPv6_CID.DHCPv6_DUID_EN.Type"}))
{
$CID_OPTION = "opt_CID_EN_nut";
$optstr = $$frame{"$base.Opt_DHCPv6_CID.DHCPv6_DUID_EN.EnterpriseNumber"};
# $cppstr .= " -D\'NUT_DUID_EN_ENNUM =hexstr(\"$optstr\")\' ";
#XXX hide modified above line
$cppstr .= " -D\'NUT_DUID_EN_ENNUM =$optstr\' ";
$optstr = $$frame{"$base.Opt_DHCPv6_CID.DHCPv6_DUID_EN.Identifier"};
$cppstr .= " -D\'NUT_DUID_EN_ID=hexstr(\"$optstr\")\' ";
}
# DUID LL, Hardware Type = 1
if(defined($$frame{"$base.Opt_DHCPv6_CID.DHCPv6_DUID_LL_Ether.Type"}))
{
$CID_OPTION = "opt_CID_LL_nut";
$optstr = $$frame{"$base.Opt_DHCPv6_CID.DHCPv6_DUID_LL_Ether.LinkLayerAddress"};
$cppstr .= " -D\'NUT_DUID_MAC_ADDR=ether(\"$optstr\")\'";
}
#DUID LL, Hardware Type = other than 1
if(defined($$frame{"$base.Opt_DHCPv6_CID.DHCPv6_DUID_LL_ANY.Type"}))
{
$CID_OPTION = "opt_CID_LL_nut";
$optstr = $$frame{"$base.Opt_DHCPv6_CID.DHCPv6_DUID_LL_ANY.HardwareType"};
$cppstr .= " -D\'NUT_DUID_HARDWARE_TYPE = $optstr\' ";
$optstr = $$frame{"$base.Opt_DHCPv6_CID.DHCPv6_DUID_LL_ANY.LinkLayerAddress"};
$cppstr .= " -D\'NUT_DUID_MAC_ADDR=hexstr(\"$optstr\")\'";
}
# print " -----------------------------------------------------------------\n";
print " cppstr = $cppstr \n";
# print " -----------------------------------------------------------------\n";
return ($cppstr);
}
##
#
sub send_reply($$$$) {
my ($if, $reply, $sol_or_req, $cpp) = @_;
my $framestring = $sol_or_req->{"Frame_Ether.Packet_IPv6.Upp_UDP"};
my @frames = grep(/Udp_DHCPv6/,split(' ',$framestring));
if(scalar(@frames) > 1 ){
vLogHTML("<B>send_reply:Receive Packet has some frames: @frames</B><BR>");
return (1, ());
}
my $base = "Frame_Ether.Packet_IPv6.Upp_UDP.$frames[0]";
$cpp = defined($cpp) ? $cpp : '';
my $optstr = "";
my $cppstr = SetCidOption($sol_or_req,$base);
print "\n cppstr = $cppstr \n";
if(defined($$sol_or_req{"$base.Identifier"}))
{
$optstr = $$sol_or_req{"$base.Identifier"};
$cppstr .= " -D\'ID_REP=$optstr\' ";
}
# set IA Options
if(defined($$sol_or_req{"$base.Opt_DHCPv6_IA_NA.Identifier"}))
{
$optstr = $$sol_or_req{"$base.Opt_DHCPv6_IA_NA.Identifier"};
$cppstr .= " -D\'IA_NA_IDENTIFIER=$optstr\' ";
}
if(defined($$sol_or_req{"$base.Opt_DHCPv6_IA_TA.Identifier"}))
{
$optstr = $$sol_or_req{"$base.Opt_DHCPv6_IA_TA.Identifier"};
$cppstr .= " -D\'IA_TA_IDENTIFIER=$optstr\' ";
}
if(defined($$sol_or_req{"$base.Opt_DHCPv6_IA_PD.Identifier"}))
{
$optstr = $$sol_or_req{"$base.Opt_DHCPv6_IA_PD.Identifier"};
$cppstr .= " -D\'IA_PD_IDENTIFIER=$optstr\' ";
}
createPacketDefinitionFile("DHCPv6_test.def");
$cppstr .= $cpp;
# print "\n cpp string is $cppstr \n ";
vCPP($cppstr);
# send DHCPv6 Reply Message
my %ret = vSend3($if, $reply);
if(defined($ret{"Frame_Ether\.Packet_IPv6\.Upp_UDP\.Udp_DHCPv6_Reply"})) {
parse_message(\%ret);
return (0, %ret) if(0 == $ret{status});
}
return (1, %ret);
}
#--------------------------------------------------------------#
# send_reply($if, $reply, $sol_or_req, $cpp) #
# #
# Notes: #
# make Reply Message by using received Request #
# SUCCESS: return (0, reply) #
# FAILURE: return (1, ???) #
#--------------------------------------------------------------#
sub send_reply1($$$$) {
my ($if, $reply, $sol_or_req, $cpp) = @_;
my $framestring = $sol_or_req->{"Frame_Ether.Packet_IPv6.Upp_UDP"};
my @frames = grep(/Udp_DHCPv6/,split(' ',$framestring));
if(scalar(@frames) > 1 ){
vLogHTML("<B>send_reply:Receive Packet has some frames: @frames</B><BR>");
return (1, ());
}
my $base = "Frame_Ether.Packet_IPv6.Upp_UDP.$frames[0]";
$cpp = defined($cpp) ? $cpp : '';
my $optstr = "";
my $cppstr = "";
# make packet definition
if(defined($$sol_or_req{"$base.Opt_DHCPv6_CID.DHCPv6_DUID_LLT_Ether.LinkLayerAddress"}))
{
$optstr = $$sol_or_req{"$base.Opt_DHCPv6_CID.DHCPv6_DUID_LLT_Ether.LinkLayerAddress"};
$cppstr .= " -D\'NUT_DUID_MAC_ADDR=ether(\"$optstr\")\' ";
}
if(defined($$sol_or_req{"$base.Opt_DHCPv6_CID.DHCPv6_DUID_LLT_Ether.Time"}))
{
$optstr = $$sol_or_req{"$base.Opt_DHCPv6_CID.DHCPv6_DUID_LLT_Ether.Time"};
$cppstr .= " -D\'NUT_DUID_TIME=$optstr\' ";
}
if(defined($$sol_or_req{"$base.Opt_DHCPv6_CID.DHCPv6_DUID_LLT_ANY.HardwareType"}))
{
$optstr = $$sol_or_req{"$base.Opt_DHCPv6_CID.DHCPv6_DUID_LLT_ANY.HardwareType"};
$cppstr .= " -D\'NUT_DUID_HARDWARE_TYPE = $optstr\' ";
}
if(defined($$sol_or_req{"$base.Opt_DHCPv6_CID.DHCPv6_DUID_LLT_ANY.LinkLayerAddress"}))
{
$optstr = $$sol_or_req{"$base.Opt_DHCPv6_CID.DHCPv6_DUID_LLT_ANY.LinkLayerAddress"};
$cppstr .= " -D\'NUT_DUID_MAC_ADDR=hexstr(\"$optstr\")\' ";
}
if(defined($$sol_or_req{"$base.Opt_DHCPv6_CID.DHCPv6_DUID_LLT_ANY.Time"}))
{
$optstr = $$sol_or_req{"$base.Opt_DHCPv6_CID.DHCPv6_DUID_LLT_ANY.Time"};
$cppstr .= " -D\'NUT_DUID_TIME=$optstr\' ";
}
if(defined($$sol_or_req{"$base.Identifier"}))
{
$optstr = $$sol_or_req{"$base.Identifier"};
$cppstr .= " -D\'ID_REP=$optstr\' ";
}
# set IA Options
if(defined($$sol_or_req{"$base.Opt_DHCPv6_IA_NA.Identifier"}))
{
$optstr = $$sol_or_req{"$base.Opt_DHCPv6_IA_NA.Identifier"};
$cppstr .= " -D\'IA_NA_IDENTIFIER=$optstr\' ";
}
if(defined($$sol_or_req{"$base.Opt_DHCPv6_IA_TA.Identifier"}))
{
$optstr = $$sol_or_req{"$base.Opt_DHCPv6_IA_TA.Identifier"};
$cppstr .= " -D\'IA_TA_IDENTIFIER=$optstr\' ";
}
if(defined($$sol_or_req{"$base.Opt_DHCPv6_IA_PD.Identifier"}))
{
$optstr = $$sol_or_req{"$base.Opt_DHCPv6_IA_PD.Identifier"};
$cppstr .= " -D\'IA_PD_IDENTIFIER=$optstr\' ";
}
createPacketDefinitionFile("DHCPv6_test.def");
$cppstr .= $cpp;
# print "\n cpp string is $cppstr \n ";
vCPP($cppstr);
# send DHCPv6 Reply Message
my %ret = vSend3($if, $reply);
if(defined($ret{"Frame_Ether\.Packet_IPv6\.Upp_UDP\.Udp_DHCPv6_Reply"})) {
parse_message(\%ret);
return (0, %ret) if(0 == $ret{status});
}
return (1, %ret);
}
#--------------------------------------------------------------#
# send_reply2($if, $reply, $sol_or_req, $cpp) #
# #
# Notes: #
# make Reply Message by using received Request #
# SUCCESS: return (0, reply) #
# FAILURE: return (1, ???) #
#--------------------------------------------------------------#
sub send_reply2($$$$) {
my ($if, $reply, $sol_or_req, $cpp) = @_;
my $framestring = $sol_or_req->{"Frame_Ether.Packet_IPv6.Upp_UDP"};
my @frames = grep(/Udp_DHCPv6/,split(' ',$framestring));
if(scalar(@frames) > 1 ){
vLogHTML("<B>send_reply:Receive Packet has some frames: @frames</B><BR>");
return (1, ());
}
my $base = "Frame_Ether.Packet_IPv6.Upp_UDP.$frames[0]";
$cpp = defined($cpp) ? $cpp : '';
my $optstr = "";
my $cppstr = "";
# make packet definition
if(defined($$sol_or_req{"$base.Opt_DHCPv6_CID.DHCPv6_DUID_LLT_Ether.LinkLayerAddress"}))
{
$optstr = $$sol_or_req{"$base.Opt_DHCPv6_CID.DHCPv6_DUID_LLT_Ether.LinkLayerAddress"};
$cppstr .= " -D\'NUT_DUID_MAC_ADDR=ether(\"$optstr\")\' ";
}
if(defined($$sol_or_req{"$base.Opt_DHCPv6_CID.DHCPv6_DUID_LLT_Ether.Time"}))
{
$optstr = $$sol_or_req{"$base.Opt_DHCPv6_CID.DHCPv6_DUID_LLT_Ether.Time"};
$cppstr .= " -D\'NUT_DUID_TIME=$optstr\' ";
}
if(defined($$sol_or_req{"$base.Opt_DHCPv6_CID.DHCPv6_DUID_LLT_ANY.HardwareType"}))
{
$optstr = $$sol_or_req{"$base.Opt_DHCPv6_CID.DHCPv6_DUID_LLT_ANY.HardwareType"};
$cppstr .= " -D\'NUT_DUID_HARDWARE_TYPE = $optstr\' ";
}
if(defined($$sol_or_req{"$base.Opt_DHCPv6_CID.DHCPv6_DUID_LLT_ANY.LinkLayerAddress"}))
{
$optstr = $$sol_or_req{"$base.Opt_DHCPv6_CID.DHCPv6_DUID_LLT_ANY.LinkLayerAddress"};
$cppstr .= " -D\'NUT_DUID_MAC_ADDR=hexstr(\"$optstr\")\' ";
}
if(defined($$sol_or_req{"$base.Opt_DHCPv6_CID.DHCPv6_DUID_LLT_ANY.Time"}))
{
$optstr = $$sol_or_req{"$base.Opt_DHCPv6_CID.DHCPv6_DUID_LLT_ANY.Time"};
$cppstr .= " -D\'NUT_DUID_TIME=$optstr\' ";
}
if(defined($$sol_or_req{"$base.Identifier"}))
{
$optstr = $$sol_or_req{"$base.Identifier"};
$cppstr .= " -D\'ID_REP=$optstr\' ";
}
# set IA Options
if(defined($$sol_or_req{"$base.Opt_DHCPv6_IA_NA.Identifier"}))
{
$optstr = $$sol_or_req{"$base.Opt_DHCPv6_IA_NA.Identifier"};
$cppstr .= " -D\'IA_NA_IDENTIFIER_1=$optstr\' ";
}
if(defined($$sol_or_req{"$base.Opt_DHCPv6_IA_TA.Identifier"}))
{
$optstr = $$sol_or_req{"$base.Opt_DHCPv6_IA_TA.Identifier"};
$cppstr .= " -D\'IA_TA_IDENTIFIER=$optstr\' ";
}
if(defined($$sol_or_req{"$base.Opt_DHCPv6_IA_PD.Identifier"}))
{
$optstr = $$sol_or_req{"$base.Opt_DHCPv6_IA_PD.Identifier"};
$cppstr .= " -D\'IA_PD_IDENTIFIER=$optstr\' ";
}
if(defined($$sol_or_req{"$base.Opt_DHCPv6_IA_NA2.Identifier"}))
{
$optstr = $$sol_or_req{"$base.Opt_DHCPv6_IA_NA2.Identifier"};
$cppstr .= " -D\'IA_NA_IDENTIFIER_2=$optstr\' ";
}
createPacketDefinitionFile("DHCPv6_test.def");
$cppstr .= $cpp;
# print "\n cpp string is $cppstr \n ";
vCPP($cppstr);
# send DHCPv6 Reply Message
my %ret = vSend3($if, $reply);
if(defined($ret{"Frame_Ether\.Packet_IPv6\.Upp_UDP\.Udp_DHCPv6_Reply"})) {
parse_message(\%ret);
return (0, %ret) if(0 == $ret{status});
}
return (1, %ret);
}
#----------------------------------------------------------------#
#sub MakeCppForReplyMessage($frame,$strRelaybase) #
# the sample of $strRelaybase #
# ".Udp_DHCPv6_RelayReply.Opt_DHCPv6_RelayMessage" #
#return $cpp #
#----------------------------------------------------------------#
sub MakeCppForReplyMessage($$){
my ($sol_or_req,$strRelaybase) = @_;
my $cpp = "";
my $strComm = "Frame_Ether.Packet_IPv6.Upp_UDP";
#Frame_Ether.Packet_IPv6.Upp_UDP.Udp_DHCPv6_RelayForward.Opt_DHCPv6_IID.Identifier
my $strIndexforIID = "$strComm.Udp_DHCPv6_RelayForward";
if(defined ($strRelaybase)){
$strComm .= $strRelaybase;
}
my @arMsg = (".Udp_DHCPv6_Request",
".Udp_DHCPv6_Solicit",
".Udp_DHCPv6_Confirm",
".Udp_DHCPv6_Renew",
".Udp_DHCPv6_Rebind",
".Udp_DHCPv6_Release",
".Udp_DHCPv6_Decline",
".Udp_DHCPv6_IID");
my $base = "";
my $optstr = "";
for (my $i = 0; $i < 7; $i++)
{
$base = $strComm.$arMsg[$i];
#vLogHTML($base);
# make packet definition
if(defined($$sol_or_req{"$base.Opt_DHCPv6_CID.DHCPv6_DUID_LLT_Ether.LinkLayerAddress"}))
{
$optstr = $$sol_or_req{"$base.Opt_DHCPv6_CID.DHCPv6_DUID_LLT_Ether.LinkLayerAddress"};
$cpp .= " -D\'NUT_DUID_MAC_ADDR=ether(\"$optstr\")\' ";
}
if(defined($$sol_or_req{"$base.Opt_DHCPv6_CID.DHCPv6_DUID_LLT_Ether.Time"}))
{
$optstr = $$sol_or_req{"$base.Opt_DHCPv6_CID.DHCPv6_DUID_LLT_Ether.Time"};
$cpp .= " -D\'NUT_DUID_TIME=$optstr\' ";
}
if(defined($$sol_or_req{"$base.Identifier"}))
{
$optstr = $$sol_or_req{"$base.Identifier"};
$cpp .= " -D\'ID_REP=$optstr\' ";
}
# set IA Options
if(defined($$sol_or_req{"$base.Opt_DHCPv6_IA_NA.Identifier"}))
{
$optstr = $$sol_or_req{"$base.Opt_DHCPv6_IA_NA.Identifier"};
$cpp .= " -D\'IA_NA_IDENTIFIER=$optstr\' ";
}
if(defined($$sol_or_req{"$base.Opt_DHCPv6_IA_TA.Identifier"}))
{
$optstr = $$sol_or_req{"$base.Opt_DHCPv6_IA_TA.Identifier"};
$cpp .= " -D\'IA_TA_IDENTIFIER=$optstr\' ";
}
if(defined($$sol_or_req{"$base.Opt_DHCPv6_IA_PD.Identifier"}))
{
$optstr = $$sol_or_req{"$base.Opt_DHCPv6_IA_PD.Identifier"};
$cpp .= " -D\'IA_PD_IDENTIFIER=$optstr\' ";
}
if(defined($$sol_or_req{"$strIndexforIID.Opt_DHCPv6_IID.Identifier"}))
{
$optstr = $$sol_or_req{"$strIndexforIID.Opt_DHCPv6_IID.Identifier"};
$cpp .= " -D\'IID_IDENTIFIER=hexstr(\"$optstr\",4)\' ";
}
last if ( ! "" eq $optstr);
}
return $cpp;
}
#--------------------------------------------------------------#
# send_reconfigure($if, $reconfigure, $rep, $cpp) #
# #
# Notes: #
# make Reply Message by using received Request #
# SUCCESS: return (0, reply) #
# FAILURE: return (1, ???) #
#--------------------------------------------------------------#
sub send_reconfigure($$$$) {
my ($if, $reconfigure, $rep, $cpp) = @_;
$cpp = defined($cpp) ? $cpp : '';
my $base = "Frame_Ether.Packet_IPv6.Upp_UDP.Udp_DHCPv6_Reply";
my $optstr = "";
#XXX 2006/06/29 modified
my $framestring = $rep->{"Frame_Ether.Packet_IPv6.Upp_UDP"};
my @frames = grep(/Udp_DHCPv6/,split(' ',$framestring));
my $base2 = "Frame_Ether.Packet_IPv6.Upp_UDP.$frames[0]";
my $cpp .= SetCidOption($rep,$base2);
# make packet definition
my ($ret,$cpp_cp) = GetSvrDUIDfromPreMsg($rep,$base);
$cpp .= $cpp_cp;
if(defined($$rep{"$base.Identifier"}))
{
$optstr = $$rep{"$base.Identifier"};
$cpp .= " -D\'ID_REP=$optstr\' ";
}
# set IA Options
if(defined($$rep{"$base.Opt_DHCPv6_IA_NA.Identifier"}))
{
$optstr = $$rep{"$base.Opt_DHCPv6_IA_NA.Identifier"};
$cpp .= " -D\'IA_NA_IDENTIFIER=$optstr\' ";
}
if(defined($$rep{"$base.Opt_DHCPv6_IA_TA.Identifier"}))
{
$optstr = $$rep{"$base.Opt_DHCPv6_IA_TA.Identifier"};
$cpp .= " -D\'IA_TA_IDENTIFIER=$optstr\' ";
}
createPacketDefinitionFile("DHCPv6_test.def");
vCPP($cpp);
# send DHCPv6 Reconfigure Message
my %ret = vSend3($if, $reconfigure);
if(defined($ret{"Frame_Ether\.Packet_IPv6\.Upp_UDP\.Udp_DHCPv6_Reconfigure"})) {
parse_message(\%ret);
return (0, %ret) if(0 == $ret{status});
}
return (1, %ret);
}
#--------------------------------------------------------------#
# send_information_request($if, $information_request, #
# $advertise, $cpp) #
# #
# Notes: #
# make information request Message #
# SUCCESS: return (0, information_request) #
# FAILURE: return (1, ???) #
#--------------------------------------------------------------#
sub send_information_request($$$$) {
my ($if, $information_request, $advertise, $cpp) = @_;
$cpp = defined($cpp) ? $cpp : '';
my $base = "Frame_Ether\.Packet_IPv6\.Upp_UDP\.Udp_DHCPv6_Advertise";
my $optstr = "";
# make packet definition
my ($ret,$cpp_cp) = GetSvrDUIDfromPreMsg($advertise,$base);
$cpp .= $cpp_cp;
#No SID option in Information-request message
createPacketDefinitionFile("DHCPv6_test.def");
vCPP($cpp);
# send DHCPv6 Information Request Message
my %ret = vSend3($if, $information_request);
if(defined($ret{"Frame_Ether\.Packet_IPv6\.Upp_UDP\.Udp_DHCPv6_InformationRequest"})) {
parse_message(\%ret);
return (0, %ret) if(0 == $ret{status});
}
return (1, %ret);
}
#--------------------------------------------------------------#
# initial_ra_w_ping($if) #
# #
# Notes: #
# Send RA #
# ping from Server1 to NUT(Global Address) #
# SUCCESS: return 0 #
# FAILURE: return 1 #
#--------------------------------------------------------------#
sub initial_ra_w_ping($$) {
my ($if, $paket) = @_;
my $IF0_NUT = $V6evalTool::NutDef{"Link0_device"};
if($INITIAL_RA){
my $ret = vRemote("dhcp6c.rmt", "stop", "$if=$IF0_NUT");
if($ret != 0) {
vLogHTML('<FONT COLOR="#FF0000">Cannot Initialize DHCPv6 Client program.</FONT><BR>');
dhcpExitFail;
};
vRecv($if, 3, 0, 0, 'rs_nut_to_server1');
vSend($if, $paket);
vSleep(5);
vSend($if, 'echorequest_server1_to_nut');
my %ret = vRecv($if, 5, 0, 0, 'ns_nutga_to_any','ns_nutga_to_any_lla','echoreply_nut_to_server1');
if ( $ret{recvFrame} eq 'echoreply_nut_to_server1'){
vLogHTML("<B>SERVER1 received Echo Reply.</B><BR>");
return 0;
}elsif($ret{recvFrame} eq 'ns_nutga_to_any'){
vSend($if, 'na_server1ga_to_nutga');
%ret = ();
%ret = vRecv($if, 5, 0, 0, 'echoreply_nut_to_server1');
if ( $ret{recvFrame} eq 'echoreply_nut_to_server1') {
vLogHTML("<B>SERVER1 received Echo Reply.</B><BR>");
return 0 ;
}
}elsif($ret{recvFrame} eq 'ns_nutga_to_any_lla'){
vSend($if, 'na_server1ga_to_nutga_lla');
%ret = ();
%ret = vRecv($if, 5, 0, 0, 'echoreply_nut_to_server1');
if ( $ret{recvFrame} eq 'echoreply_nut_to_server1') {
vLogHTML("<B>SERVER1 received Echo Reply.</B><BR>");
return 0 ;
}
}
vLogHTML("<B>SERVER1 cannot receive Echo Reply.</B><BR>");
return 1;
}
return 1;
}
#--------------------------------------------------------------#
# ping_test($if) #
# #
# Notes: #
# ping from Server1 to NUT(Global Address assigned by DHCP) #
# SUCCESS: return 0 #
# FAILURE: return 1 #
#--------------------------------------------------------------#
sub ping_test($) {
my ($if) = @_;
vLogHTML("<B># ping test from Server1 to NUT(Global Address assigned by DHCP)</B><BR>");
if($RA_BEFORE_PING){
vRecv($if, 3, 0, 0, 'rs_nut_to_server1');
vSleep(5);
# vSend($if, 'ra_server1_to_nut');
vSend($if, 'ra_server2_to_all');
}
vSend($if, 'echorequest_server1_to_nut');
my %ret = vRecv($if, 5, 0, 0, 'ns_nutga_to_any','ns_nutga_to_any_lla','echoreply_nut_to_server1');
if ( $ret{recvFrame} eq 'echoreply_nut_to_server1'){
vLogHTML("<B>SERVER1 received Echo Reply.</B><BR>");
return 0;
}elsif($ret{recvFrame} eq 'ns_nutga_to_any'){
vSend($if, 'na_server1ga_to_nutga');
%ret = ();
%ret = vRecv($if, 5, 0, 0, 'echoreply_nut_to_server1');
if ( $ret{recvFrame} eq 'echoreply_nut_to_server1') {
vLogHTML("<B>SERVER1 received Echo Reply.</B><BR>");
return 0 ;
}
}elsif($ret{recvFrame} eq 'ns_nutga_to_any_lla'){
vSend($if, 'na_server1ga_to_nutga_lla');
%ret = ();
%ret = vRecv($if, 5, 0, 0, 'echoreply_nut_to_server1');
if ( $ret{recvFrame} eq 'echoreply_nut_to_server1') {
vLogHTML("<B>SERVER1 received Echo Reply.</B><BR>");
return 0 ;
}
}
vLogHTML("<B>SERVER1 cannot receive Echo Reply.</B><BR>");
return 1;
}
#--------------------------------------------------------------#
# ping_test_addr2($if) #
# #
# Notes: #
# ping from Server1 to NUT(Global Address assigned by RA) #
# SUCCESS: return 0 #
# FAILURE: return 1 #
#--------------------------------------------------------------#
sub ping_test_addr2($) {
my ($if) = @_;
vLogHTML("<B># ping test from Server1 to NUT(Global Address assigned by RA)</B><BR>");
vSend($if, 'echorequest_server1_to_nut_addr2');
my %ret = vRecv($if, 5, 0, 0, 'ns_nutga_to_any','ns_nutga_to_any_lla','echoreply_nut_addr2_to_server1');
if ( $ret{recvFrame} eq 'echoreply_nut_addr2_to_server1'){
vLogHTML("<B>SERVER1 received Echo Reply.</B><BR>");
return 0;
}elsif($ret{recvFrame} eq 'ns_nutga_to_any'){
vSend($if, 'na_server1ga_to_nutga');
%ret = ();
%ret = vRecv($if, 5, 0, 0, 'echoreply_nut_addr2_to_server1');
if ( $ret{recvFrame} eq 'echoreply_nut_addr2_to_server1') {
vLogHTML("<B>SERVER1 received Echo Reply.</B><BR>");
return 0 ;
}
}elsif($ret{recvFrame} eq 'ns_nutga_to_any_lla'){
vSend($if, 'na_server1ga_to_nutga_lla');
%ret = ();
%ret = vRecv($if, 5, 0, 0, 'echoreply_nut_addr2_to_server1');
if ( $ret{recvFrame} eq 'echoreply_nut_addr2_to_server1') {
vLogHTML("<B>SERVER1 received Echo Reply.</B><BR>");
return 0 ;
}
}
vLogHTML("<B>SERVER1 cannot receive Echo Reply.</B><BR>");
return 1;
}
#--------------------------------------------------------------#
# ping_test_nut1($if) #
# #
# Notes: #
# ping from Server2 to NUT(Global Address assigned by DHCP) #
# SUCCESS: return 0 #
# FAILURE: return 1 #
#--------------------------------------------------------------#
sub ping_test_nut1($) {
my ($if) = @_;
vLogHTML("<B># ping test from Server2 to NUT(Link1)</B><BR>");
vSend($if, 'echorequest_server2_to_nut1');
my %ret = vRecv($if, 5, 0, 0, 'ns_nut1_ga_to_any','ns_nut1ga_to_any_lla','echoreply_nut1_to_server2');
if ( $ret{recvFrame} eq 'echoreply_nut1_to_server2'){
vLogHTML("<B>SERVER2 received Echo Reply.</B><BR>");
return (0, %ret);
}elsif($ret{recvFrame} eq 'ns_nut1_ga_to_any'){
vSend($if, 'na_server2ga_to_nut1ga');
%ret = ();
%ret = vRecv($if, 5, 0, 0, 'echoreply_nut1_to_server2');
if ( $ret{recvFrame} eq 'echoreply_nut1_to_server2') {
vLogHTML("<B>SERVER2 received Echo Reply.</B><BR>");
return (0, %ret);
}
}elsif($ret{recvFrame} eq 'ns_nut1ga_to_any_lla'){
vSend($if, 'na_server2ga_to_nut1ga_lla');
%ret = ();
%ret = vRecv($if, 5, 0, 0, 'echoreply_nut1_to_server2');
if ( $ret{recvFrame} eq 'echoreply_nut1_to_server2') {
vLogHTML("<B>SERVER2 received Echo Reply.</B><BR>");
return (0, %ret);
}
}
vLogHTML("<B>SERVER2 cannot receive Echo Reply.</B><BR>");
return (1, %ret);
}
#--------------------------------------------------------------#
# ping_nut_test($;$$$) #
# #
# Notes: #
# ping from Server($EchoName) to NUT($ReplyName $AddrNum) #
# IN: #
# $if: NUT Interface #
# $EchoName: Server(TN) that assign address to NUT #
# $ReplyName: NUT #
# $AddrNum: NUT Address Number #
# return: #
# 0 : Pass #
# 1 : Fail #
# eg. #
# ping_nut_test($IF0,server1,nut,1); #
#--------------------------------------------------------------#
sub ping_nut_test($;$$$){
my ($if, $EchoName, $ReplyName, $AddrNum) = @_;
my $SendFrameName = undef;
my $RecvFrameName1 = undef;
my $RecvFrameName2 = undef;
my $vSendFrameName = undef;
my %ret = undef;
vLogHTML("<B> Echo Request from $EchoName to $ReplyName </B><BR>");
$SendFrameName = "echorequest_".$EchoName."_to_".$ReplyName.$AddrNum;
vSend($if, $SendFrameName);
$RecvFrameName1 = "ns_".$ReplyName.$AddrNum."ga"."_to_"."any";
$RecvFrameName2 = "echoreply_".$ReplyName.$AddrNum."_to_".$EchoName;
%ret = vRecv($if, 3, 0, 0, $RecvFrameName1, $RecvFrameName2);
return 0 if ($ret{recvFrame} eq $RecvFrameName2);
$vSendFrameName = "na_".$EchoName."ga"."_to_".$ReplyName.$AddrNum."ga";
vSend($if, $vSendFrameName);
$RecvFrameName1 = "echoreply_".$ReplyName.$AddrNum."_to_".$EchoName;
%ret = vRecv($if, 5, 0, 0, $RecvFrameName1);
if ( $ret{recvFrame} eq $RecvFrameName1 ){
vLogHTML("<B>$EchoName received Echo Reply from $ReplyName$AddrNum.</B><BR>");
return 0;
}
vLogHTML("<B>$EchoName cannot receive Echo Reply.</B><BR>");
return 1;
}
#--------------------------------------------------------------#
# SetNUTAddr($$$$) #
# #
# Notes: #
# set the address of NUT(Server) #
# #
#--------------------------------------------------------------#
sub SetNUTAddr($$$$){
# Now only for host
my ($IFName,$address,$len,$type) = @_;
my $ret = vRemote('manualaddrconf.rmt',"if=$IFName","addr=$address","len=$len","type=$type");
dhcpExitFail if (0 != $ret);
}
#--------------------------------------------------------------#
# ifDown($) #
# #
# Notes: #
# interface down #
# #
#--------------------------------------------------------------#
sub ifDown($){
my ($IFName) = @_;
my $ret = vRemote("dhcp6c.rmt", "ifdown", "link0=$IFName");
if($ret != 0) {
vLogHTML('<FONT COLOR="#FF0000">Cannot down the interface of DHCPv6 Client</FONT><BR>');
dhcpExitFail;
};
}
#--------------------------------------------------------------#
# ifUp($) #
# #
# Notes: #
# interface up #
# #
#--------------------------------------------------------------#
sub ifUp($){
my ($IFName) = @_;
my $ret = vRemote("dhcp6c.rmt", "ifup", "link0=$IFName");
if($ret != 0) {
vLogHTML('<FONT COLOR="#FF0000">Cannot up the interface of DHCPv6 Client</FONT><BR>');
dhcpExitFail;
};
}
#--------------------------------------------------------------#
# vRecvPacket($ifname, $timeout, $seektime, $count, @frames) #
# Out: #
# %frame #
#--------------------------------------------------------------#
sub vRecvPacket($$$$@)
{
my ($ifname, $timeout, $seektime, $count, @frames) = @_;
my (%ret,%nd) = ((),());
my $type=$V6evalTool::NutDef{Type};
if($type eq 'host') {
%nd = (
'ns_nutlla_to_any_lla' => 'na_server1_to_nut',
'ns_nut_to_any_local' => 'na_client1_to_nut_local',
'ns_nut_to_any_global' => 'na_client1_to_nut_global',
'ns_nut_to_relay1_0' =>'na_relay1_0_to_nut',
'ns_nut_to_relay1_0_global' =>'na_relay1_0_to_nut_global',
'ns_nut_to_relay1_0_global_global' =>'na_relay1_0_to_nut_global_global',
'ns_nut_to_relay2_0' =>'na_relay2_0_to_nut',
'ns_nut_to_relay2_0_global' =>'na_relay2_0_to_nut_global',
'ns_nut_to_relay2_0_global_global' =>'na_relay2_0_to_nut_global_global',
'ns_nutga_to_any' => 'na_server1ga_to_nutga',
);
}
elsif($type eq 'router'){
%nd = (
'ns_nut_to_any_local' => 'na_client1_to_nut_local',
'ns_nut_to_any_global' => 'na_client1_to_nut_global',
'ns_nutrelay_to_client_local' => 'na_client1_to_nut_local',
'ns_nutrelay_to_client_global' => 'na_client1_to_nut_global',
'ns_nutrelay_to_server' => 'na_server1_to_nut',
'ns_nutrelay_to_relay' =>'na_relay2_to_nut'
);
}
while(1) {
%ret = vRecv3($ifname, $timeout, $seektime, $count,@frames, keys(%nd));
if($ret{'recvCount'}) {
my $continue = 0;
while(my ($recv, $send) = each(%nd)) {
if($recv && $ret{'recvFrame'} eq $recv) {
vSend($ifname, $send);
$continue ++;
}
}
if($continue) {
next;
}
}
last;
}
return(%ret);
}
#--------------------------------------------------------------#
# createPacketDefinitionFile(filename) #
# #
# Notes: #
# make packet definition #
# #
#--------------------------------------------------------------#
sub createPacketDefinitionFile($){
my ($filename) = @_;
my $OptionDesc = "";
my $portno = 546;
$OptionDesc .= "\t\toption = ".$CID_OPTION.";\n" if (! $CID_OPTION eq "");
$OptionDesc .= "\t\toption = ".$SID_OPTION.";\n" if (! $SID_OPTION eq "");
$OptionDesc .= "\t\toption = ".$IA_NA_OPTION.";\n" if (! $IA_NA_OPTION eq "");
$OptionDesc .= "\t\toption = ".$IA_NA_OPTION1.";\n" if (! $IA_NA_OPTION1 eq "");
$OptionDesc .= "\t\toption = ".$IA_TA_OPTION.";\n" if (! $IA_TA_OPTION eq "");
$OptionDesc .= "\t\toption = ".$IA_PD_OPTION.";\n" if (! $IA_PD_OPTION eq "");
$OptionDesc .= "\t\toption = ".$IA_PD_OPTION1.";\n" if (! $IA_PD_OPTION1 eq "");
$OptionDesc .= "\t\toption = ".$OptionRequest_OPTION.";\n" if (! $OptionRequest_OPTION eq "");
$OptionDesc .= "\t\toption = ".$Preference_OPTION.";\n" if (! $Preference_OPTION eq "");
$OptionDesc .= "\t\toption = ".$ElapsedTime_OPTION.";\n" if (! $ElapsedTime_OPTION eq "");
$OptionDesc .= "\t\toption = ".$Authentication_OPTION.";\n" if (! $Authentication_OPTION eq "");
$OptionDesc .= "\t\toption = ".$Authentication_OPTION2.";\n" if (! $Authentication_OPTION2 eq "");
$OptionDesc .= "\t\toption = ".$ServerUnicast_OPTION.";\n" if (! $ServerUnicast_OPTION eq "");
$OptionDesc .= "\t\toption = ".$RapidCommit_OPTION.";\n" if (! $RapidCommit_OPTION eq "");
$OptionDesc .= "\t\toption = ".$UserClass_OPTION.";\n" if (! $UserClass_OPTION eq "");
$OptionDesc .= "\t\toption = ".$VendorClass_OPTION.";\n" if (! $VendorClass_OPTION eq "");
$OptionDesc .= "\t\toption = ".$VendorSpecificInfo_OPTION.";\n" if (! $VendorSpecificInfo_OPTION eq "");
$OptionDesc .= "\t\toption = ".$IID_OPTION.";\n" if (! $IID_OPTION eq "");
$OptionDesc .= "\t\toption = ".$ReconfigureMessage_OPTION.";\n" if (! $ReconfigureMessage_OPTION eq "");
$OptionDesc .= "\t\toption = ".$ReconfigureAccept_OPTION.";\n" if (! $ReconfigureAccept_OPTION eq "");
$OptionDesc .= "\t\toption = ".$StatusCode_OPTION.";\n" if (! $StatusCode_OPTION eq "");
$OptionDesc .= "\t\toption = ".$DNS_SVR_OPTION.";\n" if (! $DNS_SVR_OPTION eq "");
$OptionDesc .= "\t\toption = ".$DNS_LST_OPTION.";\n" if (! $DNS_LST_OPTION eq "");
$OptionDesc .= "\t\toption = ".$RELAY_Msg_OPTION.";\n" if (! $RELAY_Msg_OPTION eq "");
open(OUT, ">./$filename")|| return 2;
print OUT "/* \n";
print OUT "*** DO NOT EDIT THIS FILE ***\n";
print OUT "*/\n";
#--------------------------------------------------------------#
# *** for Server Test *** #
#--------------------------------------------------------------#
# DHCPv6 Solicit: CLIENT1 ----> multicast
print OUT "FEM_dhcp6_solicit(\n";
print OUT "\tsolicit_client1_to_alldhcp,\n";
print OUT "\t_HETHER_client1_to_alldhcp,\n";
print OUT "\t{\n";
print OUT "\t_SRC(CLIENT1_LLOCAL_UCAST);\n";
print OUT "\t_DST(v6(_ALLDHCPAGENTS_MCAST_ADDR));\n";
# print OUT "\tHopLimit = 1;\n";
print OUT "\t},\n";
print OUT "\t{\n";
print OUT "\t\t_SPORT($portno);\n";
print OUT "\t\t_DPORT(547);\n";
print OUT "\t},\n";
print OUT "\t{\n";
print OUT $OptionDesc;
print OUT "\t\tIdentifier = ID_SOL;\n";
print OUT "\t}\n";
print OUT ")\n";
# DHCPv6 Solicit: CLIENT1 ----> NUT
print OUT "FEM_dhcp6_solicit(\n";
print OUT "\tsolicit_client1_to_nut,\n";
print OUT "\t_HETHER_client1_to_nut,\n";
print OUT "\t{\n";
print OUT "\t\t_SRC(CLIENT1_LLOCAL_UCAST);\n";
print OUT "\t\t_DST(NUT_LLOCAL_UCAST);\n";
print OUT "\t},\n";
print OUT "\t{\n";
print OUT "\t\t_SPORT($portno);\n";
print OUT "\t\t_DPORT(547);\n";
print OUT "\t},\n";
print OUT "\t{\n";
print OUT "\t\tIdentifier = ID_SOL;\n";
print OUT $OptionDesc;
print OUT "\t}\n";
print OUT ")\n";
# DHCPv6 Request: CLIENT1 ----> multicast
print OUT "FEM_dhcp6_request(\n";
print OUT "\trequest_client1_to_alldhcp,\n";
print OUT "\t_HETHER_client1_to_alldhcp,\n";
print OUT "\t{\n";
print OUT "\t\t_SRC(CLIENT1_LLOCAL_UCAST);\n";
print OUT "\t\t_DST(v6(_ALLDHCPAGENTS_MCAST_ADDR));\n";
print OUT "\t},\n";
print OUT "\t{\n";
print OUT "\t\t_SPORT($portno);\n";
print OUT "\t\t_DPORT(547);\n";
print OUT "\t},\n";
print OUT "\t{\n";
print OUT "\t\tIdentifier = ID_REQ;\n";
print OUT $OptionDesc;
print OUT "\t}\n";
print OUT ")\n";
# DHCPv6 Request: CLIENT1 ----> NUT
print OUT "FEM_dhcp6_request(\n";
print OUT "\trequest_client1_to_nut,\n";
print OUT "\t_HETHER_client1_to_nut,\n";
print OUT "\t{\n";
print OUT "\t\t_SRC(CLIENT1_LLOCAL_UCAST);\n";
print OUT "\t\t_DST(NUT_LLOCAL_UCAST);\n";
print OUT "\t},\n";
print OUT "\t{\n";
print OUT "\t\t_SPORT($portno);\n";
print OUT "\t\t_DPORT(547);\n";
print OUT "\t},\n";
print OUT "\t{\n";
print OUT "\t\tIdentifier = ID_REQ;\n";
print OUT $OptionDesc;
print OUT "\t}\n";
print OUT ")\n";
# DHCPv6 Information Request: CLIENT1 ----> multicast
print OUT "FEM_dhcp6_information_request(\n";
print OUT "\tinformation_request_client1_to_alldhcp,\n";
print OUT "\t_HETHER_client1_to_alldhcp,\n";
print OUT "\t{\n";
print OUT "\t _SRC(CLIENT1_LLOCAL_UCAST);\n";
print OUT "\t_DST(v6(_ALLDHCPAGENTS_MCAST_ADDR));\n";
print OUT "\t},\n";
print OUT "\t{\n";
print OUT "\t\t_SPORT($portno);\n";
print OUT "\t\t_DPORT(547);\n";
print OUT "\t},\n";
print OUT "\t{\n";
print OUT "\t\tIdentifier = ID_INFOREQ;\n";
print OUT $OptionDesc;
print OUT "\t}\n";
print OUT ")\n";
# DHCPv6 Information Request: CLIENT1 ----> NUT
print OUT "FEM_dhcp6_information_request(\n";
print OUT "\tinformation_request_client1_to_nut,\n";
print OUT "\t_HETHER_client1_to_nut,\n";
print OUT "\t{\n";
print OUT "\t _SRC(CLIENT1_LLOCAL_UCAST);\n";
print OUT "\t\t_DST(NUT_LLOCAL_UCAST);\n";
print OUT "\t},\n";
print OUT "\t{\n";
print OUT "\t\t_SPORT($portno);\n";
print OUT "\t\t_DPORT(547);\n";
print OUT "\t},\n";
print OUT "\t{\n";
print OUT "\t\tIdentifier = ID_INFOREQ;\n";
print OUT $OptionDesc;
print OUT "\t}\n";
print OUT ")\n";
# DHCPv6 Confirm: CLIENT1 ----> multicast
print OUT "FEM_dhcp6_confirm(\n";
print OUT "\tconfirm_client1_to_alldhcp,\n";
print OUT "\t_HETHER_client1_to_alldhcp,\n";
print OUT "\t{\n";
print OUT "\t_SRC(CLIENT1_LLOCAL_UCAST);\n";
print OUT "\t_DST(v6(_ALLDHCPAGENTS_MCAST_ADDR));\n";
# print OUT "\tHopLimit = 1;\n";
print OUT "\t},\n";
print OUT "\t{\n";
print OUT "\t\t_SPORT($portno);\n";
print OUT "\t\t_DPORT(547);\n";
print OUT "\t},\n";
print OUT "\t{\n";
print OUT $OptionDesc;
print OUT "\t\tIdentifier = ID_CONFIRM;\n";
print OUT "\t}\n";
print OUT ")\n";
# DHCPv6 Confirm: CLIENT1 ----> NUT
print OUT "FEM_dhcp6_confirm(\n";
print OUT "\tconfirm_client1_to_nut,\n";
print OUT "\t_HETHER_client1_to_nut,\n";
print OUT "\t{\n";
print OUT "\t\t_SRC(CLIENT1_LLOCAL_UCAST);\n";
print OUT "\t\t_DST(NUT_LLOCAL_UCAST);\n";
print OUT "\t},\n";
print OUT "\t{\n";
print OUT "\t\t_SPORT($portno);\n";
print OUT "\t\t_DPORT(547);\n";
print OUT "\t},\n";
print OUT "\t{\n";
print OUT "\t\tIdentifier = ID_CONFIRM;\n";
print OUT $OptionDesc;
print OUT "\t}\n";
print OUT ")\n";
# DHCPv6 Renew: CLIENT1 ----> multicast
print OUT "FEM_dhcp6_renew(\n";
print OUT "\trenew_client1_to_alldhcp,\n";
print OUT "\t_HETHER_client1_to_alldhcp,\n";
print OUT "\t{\n";
print OUT "\t_SRC(CLIENT1_LLOCAL_UCAST);\n";
print OUT "\t_DST(v6(_ALLDHCPAGENTS_MCAST_ADDR));\n";
# print OUT "\tHopLimit = 1;\n";
print OUT "\t},\n";
print OUT "\t{\n";
print OUT "\t\t_SPORT($portno);\n";
print OUT "\t\t_DPORT(547);\n";
print OUT "\t},\n";
print OUT "\t{\n";
print OUT $OptionDesc;
print OUT "\t\tIdentifier = ID_RENEW;\n";
print OUT "\t}\n";
print OUT ")\n";
# DHCPv6 Renew: CLIENT1 ----> NUT
print OUT "FEM_dhcp6_renew(\n";
print OUT "\trenew_client1_to_nut,\n";
print OUT "\t_HETHER_client1_to_nut,\n";
print OUT "\t{\n";
print OUT "\t\t_SRC(CLIENT1_LLOCAL_UCAST);\n";
print OUT "\t\t_DST(NUT_LLOCAL_UCAST);\n";
print OUT "\t},\n";
print OUT "\t{\n";
print OUT "\t\t_SPORT($portno);\n";
print OUT "\t\t_DPORT(547);\n";
print OUT "\t},\n";
print OUT "\t{\n";
print OUT "\t\tIdentifier = ID_RENEW;\n";
print OUT $OptionDesc;
print OUT "\t}\n";
print OUT ")\n";
# DHCPv6 Rebind: CLIENT1 ----> multicast
print OUT "FEM_dhcp6_rebind(\n";
print OUT "\trebind_client1_to_alldhcp,\n";
print OUT "\t_HETHER_client1_to_alldhcp,\n";
print OUT "\t{\n";
print OUT "\t_SRC(CLIENT1_LLOCAL_UCAST);\n";
print OUT "\t_DST(v6(_ALLDHCPAGENTS_MCAST_ADDR));\n";
# print OUT "\tHopLimit = 1;\n";
print OUT "\t},\n";
print OUT "\t{\n";
print OUT "\t\t_SPORT($portno);\n";
print OUT "\t\t_DPORT(547);\n";
print OUT "\t},\n";
print OUT "\t{\n";
print OUT $OptionDesc;
print OUT "\t\tIdentifier = ID_REBIND;\n";
print OUT "\t}\n";
print OUT ")\n";
# DHCPv6 Rebind: CLIENT1 ----> NUT
print OUT "FEM_dhcp6_rebind(\n";
print OUT "\trebind_client1_to_nut,\n";
print OUT "\t_HETHER_client1_to_nut,\n";
print OUT "\t{\n";
print OUT "\t\t_SRC(CLIENT1_LLOCAL_UCAST);\n";
print OUT "\t\t_DST(NUT_LLOCAL_UCAST);\n";
print OUT "\t},\n";
print OUT "\t{\n";
print OUT "\t\t_SPORT($portno);\n";
print OUT "\t\t_DPORT(547);\n";
print OUT "\t},\n";
print OUT "\t{\n";
print OUT "\t\tIdentifier = ID_REBIND;\n";
print OUT $OptionDesc;
print OUT "\t}\n";
print OUT ")\n";
# DHCPv6 Release: CLIENT1 ----> multicast
print OUT "FEM_dhcp6_release(\n";
print OUT "\trelease_client1_to_alldhcp,\n";
print OUT "\t_HETHER_client1_to_alldhcp,\n";
print OUT "\t{\n";
print OUT "\t_SRC(CLIENT1_LLOCAL_UCAST);\n";
print OUT "\t_DST(v6(_ALLDHCPAGENTS_MCAST_ADDR));\n";
# print OUT "\tHopLimit = 1;\n";
print OUT "\t},\n";
print OUT "\t{\n";
print OUT "\t\t_SPORT($portno);\n";
print OUT "\t\t_DPORT(547);\n";
print OUT "\t},\n";
print OUT "\t{\n";
print OUT $OptionDesc;
print OUT "\t\tIdentifier = ID_RELEASE;\n";
print OUT "\t}\n";
print OUT ")\n";
# DHCPv6 Release: CLIENT1 ----> NUT
print OUT "FEM_dhcp6_release(\n";
print OUT "\trelease_client1_to_nut,\n";
print OUT "\t_HETHER_client1_to_nut,\n";
print OUT "\t{\n";
print OUT "\t\t_SRC(CLIENT1_LLOCAL_UCAST);\n";
print OUT "\t\t_DST(NUT_LLOCAL_UCAST);\n";
print OUT "\t},\n";
print OUT "\t{\n";
print OUT "\t\t_SPORT($portno);\n";
print OUT "\t\t_DPORT(547);\n";
print OUT "\t},\n";
print OUT "\t{\n";
print OUT "\t\tIdentifier = ID_RELEASE;\n";
print OUT $OptionDesc;
print OUT "\t}\n";
print OUT ")\n";
# DHCPv6 Decline: CLIENT1 ----> multicast
print OUT "FEM_dhcp6_decline(\n";
print OUT "\tdecline_client1_to_alldhcp,\n";
print OUT "\t_HETHER_client1_to_alldhcp,\n";
print OUT "\t{\n";
print OUT "\t_SRC(CLIENT1_LLOCAL_UCAST);\n";
print OUT "\t_DST(v6(_ALLDHCPAGENTS_MCAST_ADDR));\n";
# print OUT "\tHopLimit = 1;\n";
print OUT "\t},\n";
print OUT "\t{\n";
print OUT "\t\t_SPORT($portno);\n";
print OUT "\t\t_DPORT(547);\n";
print OUT "\t},\n";
print OUT "\t{\n";
print OUT $OptionDesc;
print OUT "\t\tIdentifier = ID_DECLINE;\n";
print OUT "\t}\n";
print OUT ")\n";
# DHCPv6 Decline: CLIENT1 ----> NUT
print OUT "FEM_dhcp6_decline(\n";
print OUT "\tdecline_client1_to_nut,\n";
print OUT "\t_HETHER_client1_to_nut,\n";
print OUT "\t{\n";
print OUT "\t\t_SRC(CLIENT1_LLOCAL_UCAST);\n";
print OUT "\t\t_DST(NUT_LLOCAL_UCAST);\n";
print OUT "\t},\n";
print OUT "\t{\n";
print OUT "\t\t_SPORT($portno);\n";
print OUT "\t\t_DPORT(547);\n";
print OUT "\t},\n";
print OUT "\t{\n";
print OUT "\t\tIdentifier = ID_DECLINE;\n";
print OUT $OptionDesc;
print OUT "\t}\n";
print OUT ")\n";
#--------------------------------------------------------------#
# For Relay agent test #
#-------------------- From Here -------------------------------#
# DHCPv6 Advertise: SERVER1 ----> client1
print OUT "FEM_dhcp6_advertise(\n";
print OUT "\tadvertise_server1_to_client1,\n";
print OUT "\t_HETHER_server1_to_client1,\n";
print OUT "\t{\n";
print OUT "\t_SRC(SERVER1_LLOCAL_UCAST);\n";
print OUT "\t_DST(CLIENT1_LLOCAL_UCAST);\n";
# print OUT "\tHopLimit = 1;\n";
print OUT "\t},\n";
print OUT "\t{\n";
print OUT "\t\t_SPORT($portno);\n"; $portno++;
print OUT "\t\t_DPORT(546);\n";
print OUT "\t},\n";
print OUT "\t{\n";
print OUT $OptionDesc;
print OUT "\t\tIdentifier = ID_ADV;\n";
print OUT "\t}\n";
print OUT ")\n";
# DHCPv6 Reply: SERVER1 ----> NUT
print OUT "FEM_dhcp6_reply(\n";
print OUT "\treply_server1_to_client1,\n";
print OUT "\t_HETHER_server1_to_client1,\n";
print OUT "\t{\n";
print OUT "\t_SRC(SERVER1_LLOCAL_UCAST);\n";
print OUT "\t_DST(CLIENT1_LLOCAL_UCAST);\n";
# print OUT "\tHopLimit = 1;\n";
print OUT "\t},\n";
print OUT "\t{\n";
print OUT "\t\t_SPORT($portno);\n"; $portno++;
print OUT "\t\t_DPORT(546);\n";
print OUT "\t},\n";
print OUT "\t{\n";
print OUT $OptionDesc;
print OUT "\t\tIdentifier = ID_REP;\n";
print OUT "\t}\n";
print OUT ")\n";
# DHCPv6 Reconfigure: SERVER1 ----> Client1
print OUT "FEM_dhcp6_reconfigure(\n";
print OUT "\treconfigure_server1_to_client1,\n";
print OUT "\t_HETHER_server1_to_client1,\n";
print OUT "\t{\n";
print OUT "\t_SRC(SERVER1_LLOCAL_UCAST);\n";
print OUT "\t_DST(CLIENT1_LLOCAL_UCAST);\n";
# print OUT "\tHopLimit = 1;\n";
print OUT "\t},\n";
print OUT "\t{\n";
print OUT "\t\t_SPORT($portno);\n"; $portno++;
print OUT "\t\t_DPORT(546);\n";
print OUT "\t},\n";
print OUT "\t{\n";
print OUT $OptionDesc;
print OUT "\t\tIdentifier = ID_RECONF;\n";
print OUT "\t}\n";
print OUT ")\n";
#-------------------- To Here ---------------------------------#
# DHCPv6 Advertise: SERVER1 ----> NUT
print OUT "FEM_dhcp6_advertise(\n";
print OUT "\tadvertise_server1_to_nut,\n";
print OUT "\t_HETHER_server1_to_nut,\n";
print OUT "\t{\n";
print OUT "\t_SRC(SERVER1_LLOCAL_UCAST);\n";
print OUT "\t_DST(NUT_LLOCAL_UCAST);\n";
# print OUT "\tHopLimit = 1;\n";
print OUT "\t},\n";
print OUT "\t{\n";
print OUT "\t\t_SPORT($portno);\n"; $portno++;
print OUT "\t\t_DPORT(546);\n";
print OUT "\t},\n";
print OUT "\t{\n";
print OUT $OptionDesc;
print OUT "\t\tIdentifier = ID_ADV;\n";
print OUT "\t}\n";
print OUT ")\n";
# DHCPv6 Advertise: SERVER2 ----> NUT
print OUT "FEM_dhcp6_advertise(\n";
print OUT "\tadvertise_server2_to_nut,\n";
print OUT "\t_HETHER_server2_to_nut,\n";
print OUT "\t{\n";
print OUT "\t_SRC(SERVER2_LLOCAL_UCAST);\n";
print OUT "\t_DST(NUT_LLOCAL_UCAST);\n";
# print OUT "\tHopLimit = 1;\n";
print OUT "\t},\n";
print OUT "\t{\n";
print OUT "\t\t_SPORT($portno);\n"; $portno++;
print OUT "\t\t_DPORT(546);\n";
print OUT "\t},\n";
print OUT "\t{\n";
print OUT $OptionDesc;
print OUT "\t\tIdentifier = ID_ADV;\n";
print OUT "\t}\n";
print OUT ")\n";
# DHCPv6 Reply: SERVER1 ----> NUT
print OUT "FEM_dhcp6_reply(\n";
print OUT "\treply_server1_to_nut,\n";
print OUT "\t_HETHER_server1_to_nut,\n";
print OUT "\t{\n";
print OUT "\t_SRC(SERVER1_LLOCAL_UCAST);\n";
print OUT "\t_DST(NUT_LLOCAL_UCAST);\n";
# print OUT "\tHopLimit = 1;\n";
print OUT "\t},\n";
print OUT "\t{\n";
print OUT "\t\t_SPORT($portno);\n"; $portno++;
print OUT "\t\t_DPORT(546);\n";
print OUT "\t},\n";
print OUT "\t{\n";
print OUT $OptionDesc;
print OUT "\t\tIdentifier = ID_REP;\n";
print OUT "\t}\n";
print OUT ")\n";
# DHCPv6 Reply: SERVER2 ----> NUT
print OUT "FEM_dhcp6_reply(\n";
print OUT "\treply_server2_to_nut,\n";
print OUT "\t_HETHER_server2_to_nut,\n";
print OUT "\t{\n";
print OUT "\t_SRC(SERVER2_LLOCAL_UCAST);\n";
print OUT "\t_DST(NUT_LLOCAL_UCAST);\n";
# print OUT "\tHopLimit = 1;\n";
print OUT "\t},\n";
print OUT "\t{\n";
print OUT "\t\t_SPORT($portno);\n"; $portno++;
print OUT "\t\t_DPORT(546);\n";
print OUT "\t},\n";
print OUT "\t{\n";
print OUT $OptionDesc;
print OUT "\t\tIdentifier = ID_REP;\n";
print OUT "\t}\n";
print OUT ")\n";
# DHCPv6 Reconfigure: SERVER1 ----> NUT
print OUT "FEM_dhcp6_reconfigure(\n";
print OUT "\treconfigure_server1_to_nut,\n";
print OUT "\t_HETHER_server1_to_nut,\n";
print OUT "\t{\n";
print OUT "\t\t_SRC(SERVER1_LLOCAL_UCAST);\n";
print OUT "\t\t_DST(NUT_LLOCAL_UCAST);\n";
# print OUT "\t\tHopLimit = 1;\n";
print OUT "\t},\n";
print OUT "\t{\n";
print OUT "\t\t_SPORT($portno);\n"; $portno++;
print OUT "\t\t_DPORT(546);\n";
print OUT "\t},\n";
print OUT "\t{\n";
print OUT "\t$OptionDesc";
# print OUT "\t\tIdentifier = ID_RECONF;\n";
print OUT "\t\tIdentifier = 0;\n";
print OUT "\t}\n";
print OUT ")\n";
close(OUT);
return 0;
}
#--------------------------------------------------------------#
# clear_options() #
# #
# Notes: #
# clear global variables xx_OPTIONs #
#--------------------------------------------------------------#
sub clear_options(){
my @def_options = (
\$CID_OPTION,
\$SID_OPTION,
\$IA_NA_OPTION,
\$IA_NA_OPTION1,
\$IA_TA_OPTION,
\$IA_PD_OPTION,
\$IA_PD_OPTION1,
\$OptionRequest_OPTION,
\$Preference_OPTION,
\$ElapsedTime_OPTION,
\$Authentication_OPTION,
\$Authentication_OPTION2,
\$ServerUnicast_OPTION,
\$RapidCommit_OPTION,
\$UserClass_OPTION,
\$VendorClass_OPTION,
\$VendorSpecificInfo_OPTION,
\$IID_OPTION,
\$ReconfigureMessage_OPTION,
\$ReconfigureAccept_OPTION,
\$StatusCode_OPTION,
\$DNS_SVR_OPTION,
\$DNS_LST_OPTION,
\$RELAY_Msg_OPTION,
);
foreach my $def_option (@def_options){
$$def_option = "";
}
return 0;
}
#--------------------------------------------------------------#
# compare_options($frame1, $frame2, $optnum) #
# #
# Notes: #
# compare options in frame1 and frame2 #
# MATCH: return 0 #
# UNMATCH: return 1 #
#--------------------------------------------------------------#
sub compare_options($$$) {
my ($cmp_frame1, $cmp_frame2, $optnum) = @_;
my $unmatch = 0;
my $base1;
my $base2;
my $optbase1;
my $optbase2;
foreach(keys %dhcp6_messages) {
$base1 = $dhcp6_messages{$_};
last if (defined($$cmp_frame1{$base1}));
$base1 = "";
}
foreach(keys %dhcp6_messages) {
$base2 = $dhcp6_messages{$_};
last if (defined($$cmp_frame2{$base2}));
$base2 = "";
}
foreach(keys %option_defs) {
if (0 != ($_ & $optnum)) {
vLogHTML("<B>Comparing $option_defs{$_} </B><BR>");
$optbase1 = "$base1"."."."$option_defs{$_}";
$optbase2 = "$base2"."."."$option_defs{$_}";
if (!defined ($$cmp_frame1{"$optbase1"}) || $$cmp_frame1{"$optbase1"} eq '' ) {
vLogHTML("<FONT COLOR=\"#FF0000\"><B>not found: $optbase1 in Packet</B><BR><BR></FONT>");
$unmatch++;
} elsif (!defined ($$cmp_frame2{"$optbase2"}) || $$cmp_frame2{"$optbase2"} eq '') {
vLogHTML("<FONT COLOR=\"#FF0000\"><B>not found: $optbase2 in Packet</B><BR><BR></FONT>");
$unmatch++;
} elsif (!($$cmp_frame1{"$optbase1"} eq $$cmp_frame2{"$optbase2"})) {
my $msg = "<b><font color='red'>$optbase1 unmatched.</font></b>:";
$msg .= $$cmp_frame1{"$optbase1"};
$msg .= " != ";
$msg .= $$cmp_frame2{"$optbase2"};
$msg .= "<BR>";
vLogHTML($msg);
$unmatch++;
} else {
my $cmp_base1 = $optbase1;
my $cmp_base2 = $optbase2;
$unmatch += compare_option($cmp_frame1,"$cmp_base1", $cmp_frame2,"$cmp_base2");
}
}
}
return 0 if (0 == $unmatch);
return 1;
}
sub compare_option($$$$) {
my ($cmp_frame1,$tmp_base1, $cmp_frame2,$tmp_base2) = @_;
my $unmatch = 0;
foreach(split(" ", $$cmp_frame1{"$tmp_base1"})) {
if (! defined($$cmp_frame1{"$tmp_base1.$_"})){
return 0;
}
if ($$cmp_frame1{"$tmp_base1.$_"} eq $$cmp_frame2{"$tmp_base2.$_"}) {
my $msg = "<b><font color='blue'>$_ matched.</font></b>:";
$msg .= $$cmp_frame1{"$tmp_base1.$_"};
$msg .= " == ";
$msg .= $$cmp_frame2{"$tmp_base2.$_"};
$msg .= "<BR>";
vLogHTML($msg);
$unmatch = compare_option($cmp_frame1,"$tmp_base1.$_",$cmp_frame2,"$tmp_base2.$_");
} else {
my $msg = "<b><font color='red'>$_ unmatched.</font></b>:";
$msg .= $$cmp_frame1{"$tmp_base1.$_"};
$msg .= " != ";
$msg .= $$cmp_frame2{"$tmp_base2.$_"};
$msg .= "<BR>";
vLogHTML($msg);
return 1;
}
}
return $unmatch;
}
#--------------------------------------------------------------#
# chkMsgAfterRelay(\$Org_frame, \$Frame_Relay) #
# #
# Notes: #
# compare messages between before relay & after relay #
# MATCH: return 0 #
# UNMATCH: return 1 #
#--------------------------------------------------------------#
sub chkMsgAfterRelay($$) {
my ($ref_org_frame,$ref_frame_Relay) = @_;
my $strBaseIndex = "Frame_Ether.Packet_IPv6.Upp_UDP";
#Get the Relay type(Relay-forward or Relay-reply)
#Hdr_UDP Udp_DHCPv6_RelayForward
my $strRelayIndex = $$ref_frame_Relay{"$strBaseIndex"};
return 1 if(!defined($strRelayIndex));
if($strRelayIndex =~ /RelayForward/){
$strRelayIndex = $strBaseIndex.".Udp_DHCPv6_RelayForward.Opt_DHCPv6_RelayMessage.";
}
elsif ($strRelayIndex =~ /RelayReply/){
$strRelayIndex = $strBaseIndex.".Udp_DHCPv6_RelayReply.Opt_DHCPv6_RelayMessage.";
}
#Get the Org Msg type
#Sample: Frame_Ether.Packet_IPv6.Upp_UDP.Udp_DHCPv6_Solicit
my ($ret,$orgMsgtype) = getMsgTypeLocStr($ref_org_frame);
DebugStrOut("the full original Msg string is $orgMsgtype<BR>");
if(1== $ret){
return 1;
}
my $Msgtype = undef;
if($orgMsgtype =~ /Frame_Ether.Packet_IPv6.Upp_UDP.(.*)/){
$Msgtype = $1;
DebugStrOut("The original Msg type is $Msgtype<BR>");
}
#Compare the contents between 2 frames
my $str_org_key = undef;
foreach (keys %$ref_org_frame){
$str_org_key = $_;
if($str_org_key=~ /Frame_Ether.Packet_IPv6.Upp_UDP.$Msgtype(.*)/){
if($$ref_org_frame{$str_org_key} ne $$ref_frame_Relay{"$strRelayIndex$Msgtype".$1}){
DebugStrOut("orgin: $str_org_key --> $$ref_org_frame{$str_org_key}<BR>");
my $temp = "$strRelayIndex$Msgtype".$1;
DebugStrOut("Relay: $temp $$ref_frame_Relay{$temp}<BR>");
return 1;
}
}
}
vLogHTML("Relayed message is consitent with the orginal message!<BR>");
return 0;
}
#--------------------------------------------------------------#
# options_exist($frame, $optnum) #
# #
# Notes: #
# check if specified options exist or not. #
# EXIST: return 0 #
# NOT EXIST: return 1 #
#--------------------------------------------------------------#
sub options_exist($$) {
my ($frame, $optnum) = @_;
my $targetopt = "";
my $notfound = 0;
my $base;
vLogHTML("Checking Options...<BR>");
foreach(keys %dhcp6_messages) {
$base = $dhcp6_messages{$_};
last if (defined($$frame{$base}));
$base = "";
}
foreach(keys %option_defs) {
if (0 != ($_ & $optnum)) {
vLogHTML("Checking $option_defs{$_} ");
if (! defined($$frame{"$base"."."."$option_defs{$_}"})) {
vLogHTML("<B>$option_defs{$_} not found</B><BR>");
$notfound++;
}
else {
vLogHTML("<B>$option_defs{$_} found<BR></B>");
}
}
}
return 1 if (0 != $notfound);
return 0;
}
#--------------------------------------------------------------#
# chk_statuscode($ref_frame,$code) #
# #
# Notes: #
# The $code is value of the status code #
# return 0 success 1 fail #
# #
#--------------------------------------------------------------#
sub chk_statuscode($$) {
my ($ref_frame,$status_code) = @_;
my $statusName = get_statuscode_string($status_code);
my $indexstr = undef;
foreach (keys (%$ref_frame)){
$indexstr = $_;
#vLogHTML("string index $indexstr <BR>");
if($indexstr =~ /(.*)Opt_DHCPv6_StatusCode([2-9]*).StatusCode([1-9]*)$/){
#vLogHTML("matched string index $indexstr ,value $$ref_frame{$indexstr}<BR>");
#vLogHTML("expected status: $status_code<BR>");
if($status_code == $$ref_frame{$indexstr}){
vLogHTML("The status code $statusName has been returned<BR>");
return 0;
}
}
}
vLogHTML("The status code $statusName has not been returned<BR>");
return 1;
}
#--------------------------------------------------------------#
# get_statuscode_string($code) #
# #
# Notes: #
# return Status Codes Name #
# #
#--------------------------------------------------------------#
sub get_statuscode_string($) {
my ($val) = @_;
return $status_codes{$val};
}
#--------------------------------------------------------------#
# get_optname_string($code) #
# #
# Notes: #
# return Status Codes Name #
# #
#--------------------------------------------------------------#
sub get_optname_string($) {
my ($val) = @_;
return $option_codes{$val};
}
#--------------------------------------------------------------#
# parse_message($frame) #
# #
# Notes: #
# parse and show DHCPv6 Messages #
# #
#--------------------------------------------------------------#
sub parse_message($) {
my ($frame) = @_;
my $base;
my $msgType;
foreach(keys %dhcp6_messages) {
$base = $dhcp6_messages{$_};
if (defined($$frame{"$base"})) {
$msgType = $_;
last;
}
$base = "";
}
message_output($frame,$msgType,$base);
return;
}
#--------------------------------------------------------------#
# get_IA_NA_number($frame) #
# #
# Notes: #
# From message,get the number of IA_NA option #
# #
# IN: #
# $frame #
# return: #
# 0: No IA_NA option #
# others: number of IA_NA option #
# #
#--------------------------------------------------------------#
sub get_IA_NA_number($) {
my ($frame) = @_;
my $base;
foreach(keys %dhcp6_messages) {
$base = $dhcp6_messages{$_};
if (defined($$frame{"$base"})) {
last;
}
$base = "";
}
if(!defined($$frame{"$base"."."."Opt_DHCPv6_IA_NA.Identifier"})){
return 0;
}
my $number = 1;
my $num = $number + 1;
while(defined($$frame{$base."."."Opt_DHCPv6_IA_NA".$num."."."Identifier"})){
# vLogHTML("<B><FONT COLOR=\"#FF0000\">$base.Opt_DHCPv6_IA_NA$num.Identifier</FONT></B><BR>");
$num ++;
}
if($num > 2){
$number = $num - 1;
}
return $number;
}
#--------------------------------------------------------------#
# get_IA_PD_number($frame) #
# #
# Notes: #
# From message,get the number of IA_PD option #
# #
# IN: #
# $frame #
# return: #
# 0: No IA_PD option #
# others: number of IA_PD option #
# #
#--------------------------------------------------------------#
sub get_IA_PD_number($) {
my ($frame) = @_;
my $base;
foreach(keys %dhcp6_messages) {
$base = $dhcp6_messages{$_};
if (defined($$frame{"$base"})) {
last;
}
$base = "";
}
if(!defined($$frame{"$base"."."."Opt_DHCPv6_IA_PD.Identifier"})){
return 0;
}
my $number = 1;
my $num = $number + 1;
while(defined($$frame{$base."."."Opt_DHCPv6_IA_PD".$num."."."Identifier"})){
# vLogHTML("<B><FONT COLOR=\"#FF0000\">$base.Opt_DHCPv6_IA_PD$num.Identifier</FONT></B><BR>");
$num ++;
}
if($num > 2){
$number = $num -1;
}
return $number;
}
#--------------------------------------------------------------#
# get_IA_Prefix_number($frame) #
# #
# Notes: #
# From message,get the number of IA_PD Prefix option #
# #
# IN: #
# $frame #
# return: #
# 0: No IA_PD Prefix option #
# others: number of IA_PD Prefix option #
# #
#--------------------------------------------------------------#
sub get_IA_Prefix_number($){
my ($frame) = @_;
my $base;
foreach(keys %dhcp6_messages) {
$base = $dhcp6_messages{$_};
if (defined($$frame{"$base"})) {
last;
}
$base = "";
}
if(!defined($$frame{"$base"."."."Opt_DHCPv6_IA_PD.Opt_DHCPv6_IA_Prefix.Code"})){
return 0;
}
my $number = 1;
my $num = $number + 1;
while(defined($$frame{$base."."."Opt_DHCPv6_IA_PD.Opt_DHCPv6_IA_Prefix".$num."."."Code"})){
$num ++;
}
if($num > 2){
$number = $num -1;
}
return $number;
}
#--------------------------------------------------------------#
# CompareTimeUpdateCompletely($ref_frame1,$ref_frame2,$strMsgType1,$strMsgType2) #
# Notes: #
#check if the message has updated completely #
# #
# IN: #
# $ref_frame1 #
# $ref_frame2 #
# $strMsgType1 #
# $strMsgType2 #
# return: #
# 0: Has update completely #
# 1: Not update #
# #
#--------------------------------------------------------------#
sub CompareTimeUpdateCompletely($$$$){
my ($ref_frame1,$ref_frame2,$strMsgType1,$strMsgType2) = @_;
my $strBase1 = $dhcp6_messages{$strMsgType1};
my $strBase2 = $dhcp6_messages{$strMsgType2};
#check the new lifetimes & T1/T2 times
my $Base_T1 =$$ref_frame1{"$strBase1.Opt_DHCPv6_IA_NA.Time1"};
my $Base_T2 =$$ref_frame1{"$strBase1.Opt_DHCPv6_IA_NA.Time2"};
my $T1 = $$ref_frame2{"$strBase2.Opt_DHCPv6_IA_NA.Time1"};
my $T2 = $$ref_frame2{"$strBase2.Opt_DHCPv6_IA_NA.Time2"};
my $Base_PreTime = $$ref_frame1{"$strBase1.Opt_DHCPv6_IA_NA.Opt_DHCPv6_IA_Address.PreferredLifetime"};
my $Base_LifeTime = $$ref_frame1{"$strBase1.Opt_DHCPv6_IA_NA.Opt_DHCPv6_IA_Address.ValidLifetime"};
my $PreTime = $$ref_frame2{"$strBase2.Opt_DHCPv6_IA_NA.Opt_DHCPv6_IA_Address.PreferredLifetime"};
my $LifeTime = $$ref_frame2{"$strBase2.Opt_DHCPv6_IA_NA.Opt_DHCPv6_IA_Address.ValidLifetime"};
#vLogHTML("$strBase1.Opt_DHCPv6_IA_NA.Time1");
if(!defined($Base_PreTime)|| !defined($Base_LifeTime)|| !defined($Base_T1) || !defined($Base_T2)){
vLogHTML("<B>The IA option in $strMsgType1 is not correctly.</B><BR>");
return 1;
}
if(!defined($PreTime)|| !defined($LifeTime)|| !defined($T1) || !defined($T2)){
vLogHTML("<B>The IA option in $strMsgType2 is not correctly.</B><BR>");
return 1;
}
if ($Base_T1 == $T1){
vLogHTML("Invalid T1,(Not update)");
return 1;
}
if ($Base_T2 == $T2){
vLogHTML("Invalid T2,(Not update)");
return 1;
}
if ($Base_PreTime == $PreTime){
vLogHTML("Invalid Preferred life time,(Not update)");
return 1;
}
if ($Base_LifeTime == $LifeTime){
vLogHTML("Invalid Valid life time,(Not update)");
return 1;
}
return 0;
}
#-------------------------------------------------------------------------
#message_output($frame,$msgtype,$basestr)
#
#------------------------------------------------------------------------
sub message_output($$$){
my ($frame,$msgType,$orgbase) = @_;
my $optbase = undef;
my $optionstr = undef;
my $base = undef;
# HTML start
if( "Relay Message option" eq $msgType){
vLogHTML("<B>Relay Message Option </B><BR>");
foreach(keys %dhcp6_messages_title) {
$base = "$orgbase.".$dhcp6_messages_title{$_};
if (defined($$frame{"$base"})) {
$msgType = $_;
last;
}
$base = "";
}
if("" ne $base){
vLogHTML("<B>$msgType Message in Relay Message Option</B><BR>");
}
}else{
vLogHTML("<B>$msgType Message</B><BR>");
$base = $orgbase;
}
vLogHTML("<table BORDER=1>");
vLogHTML("<tr><td>DHCPv6 Option</td><td>Values</td></tr>");
foreach(keys %option_defs) {
my $i = 0;
$optbase = "$base"."."."$option_defs{$_}";
$optionstr = "";
if (! defined($$frame{"$optbase"})) {
next;
}
# Opt_DHCPv6_CID or Opt_DHCPv6_SID
if (("Opt_DHCPv6_CID" eq $option_defs{$_}) || ("Opt_DHCPv6_SID" eq $option_defs{$_})) {
if(defined($$frame{"$optbase\.DHCPv6_DUID_LLT_Ether"})) {
$optionstr .= "<B>DUID-LLT</B> HardwareType = ".$$frame{"$optbase\.DHCPv6_DUID_LLT_Ether\.HardwareType"}."<BR>";
$optionstr .= "<B>DUID-LLT</B> MAC = ".$$frame{"$optbase\.DHCPv6_DUID_LLT_Ether\.LinkLayerAddress"}."<BR>";
$optionstr .= "<B>DUID-LLT</B> TIME = ".$$frame{"$optbase\.DHCPv6_DUID_LLT_Ether\.Time"}."<BR>";
}
if(defined($$frame{"$optbase\.DHCPv6_DUID_LLT_ANY"})) {
$optionstr .= "<B>DUID-LLT(not Ethernet)</B> MAC= ".$$frame{"$optbase\.DHCPv6_DUID_LLT_ANY\.LinkLayerAddress"}."<BR>";
$optionstr .= "<B>DUID-LLT(not Ethernet)</B> TIME= ".$$frame{"$optbase\.DHCPv6_DUID_LLT_ANY\.Time"}."<BR>";
}
if(defined($$frame{"$optbase\.DHCPv6_DUID_EN"})) {
$optionstr .= "<B>DUID-EN</B> EnterpriseNumber= ".$$frame{"$optbase\.DHCPv6_DUID_EN\.EnterpriseNumber"}."<BR>";
$optionstr .= "<B>DUID-EN</B> Identifier= ".$$frame{"$optbase\.DHCPv6_DUID_EN\.Identifier"}."<BR>";
}
if(defined($$frame{"$optbase\.DHCPv6_DUID_LL_Ether"})) {
$optionstr .= "<B>DUID-LL</B> HardwareType = ".$$frame{"$optbase\.DHCPv6_DUID_LL_Ether\.HardwareType"}."<BR>";
$optionstr .= "<B>DUID-LL</B> LinkLayerAddress= ".$$frame{"$optbase\.DHCPv6_DUID_LL_Ether\.LinkLayerAddress"}."<BR>";
}
if(defined($$frame{"$optbase\.DHCPv6_DUID_ANY"})) {
$optionstr .= "<B>DUID (unknown)</B><BR>";
}
}
# Opt_DHCPv6_IA_NA (process multi- IA_NA)
if ("Opt_DHCPv6_IA_NA" eq $option_defs{$_}) {
$optionstr .= "<B>Option 1</B>"."<BR>";
$optionstr .= "Identifier= ".$$frame{"$optbase\.Identifier"}."<BR>";
$optionstr .= "T1= ".$$frame{"$optbase\.Time1"}."<BR>";
$optionstr .= "T2= ".$$frame{"$optbase\.Time2"}."<BR>";
if(defined($$frame{"$optbase.Opt_DHCPv6_IA_Address"})) {
$optionstr .= "<B>#IA_Addr Option</B><BR>";
$optionstr .= "Addr= ".$$frame{"$optbase\.Opt_DHCPv6_IA_Address\.Address"}."<BR>";
$optionstr .= "PreferredLifetime= ".$$frame{"$optbase\.Opt_DHCPv6_IA_Address\.PreferredLifetime"}."<BR>";
$optionstr .= "ValidLifetime= ".$$frame{"$optbase\.Opt_DHCPv6_IA_Address\.ValidLifetime"}."<BR>";
if(defined($$frame{"$optbase.Opt_DHCPv6_IA_Address.Opt_DHCPv6_StatusCode"})) {
$optionstr .= "<B>#StatusCode Option</B><BR>";
$optionstr .= "StatusCode= ".$$frame{"$optbase\.Opt_DHCPv6_IA_Address\.Opt_DHCPv6_StatusCode\.StatusCode"}." ";
$optionstr .= get_statuscode_string($$frame{"$optbase\.Opt_DHCPv6_IA_Address\.Opt_DHCPv6_StatusCode\.StatusCode"})." <BR>";
}
}
my $number = 2;
# while(defined($$frame{"$optbase.Opt_DHCPv6_IA_Address$number"})){
# $optionstr .= "<B>#IA_Addr Option $number</B><BR>";
# $optionstr .= "Addr= ".$$frame{"$optbase\.Opt_DHCPv6_IA_Address$number\.Address"}."<BR>";
# $optionstr .= "PreferredLifetime= ".$$frame{"$optbase\.Opt_DHCPv6_IA_Address$number\.PreferredLifetime"}."<BR>";
# $optionstr .= "ValidLifetime= ".$$frame{"$optbase\.Opt_DHCPv6_IA_Address$number\.ValidLifetime"}."<BR>";
# if(defined($$frame{"$optbase.Opt_DHCPv6_IA_Address$number.Opt_DHCPv6_StatusCode"})) {
# $optionstr .= "<B>#StatusCode Option</B><BR>";
# $optionstr .= "StatusCode= ".$$frame{"$optbase\.Opt_DHCPv6_IA_Address$number\.Opt_DHCPv6_StatusCode\.StatusCode"}." ";
# $optionstr .= get_statuscode_string($$frame{"$optbase\.Opt_DHCPv6_IA_Address$number\.Opt_DHCPv6_StatusCode\.StatusCode"})." <BR>";
#
# }
# $number ++ ;
#}
if(defined($$frame{"$optbase.Opt_DHCPv6_IA_Address2"})){
$optionstr .= "<B>#IA_Addr Option 2</B><BR>";
$optionstr .= "Addr= ".$$frame{"$optbase.Opt_DHCPv6_IA_Address2.Address"}."<BR>";
$optionstr .= "PreferredLifetime= ".$$frame{"$optbase.Opt_DHCPv6_IA_Address2\.PreferredLifetime"}."<BR>";
$optionstr .= "ValidLifetime= ".$$frame{"$optbase.Opt_DHCPv6_IA_Address2\.ValidLifetime"}."<BR>";
if(defined($$frame{"$optbase.Opt_DHCPv6_IA_Address2\.Opt_DHCPv6_StatusCode"})){
$optionstr .= "<B>#StatusCode Option</B><BR>";
$optionstr .= "StatusCode= ".$$frame{"$optbase.Opt_DHCPv6_IA_Address2\.Opt_DHCPv6_StatusCode\.StatusCode"}." ";
$optionstr .= get_statuscode_string($$frame{"$optbase.Opt_DHCPv6_IA_Address2\.Opt_DHCPv6_StatusCode\.StatusCode"})." <BR>";
}
}
#if(defined($$frame{"$optbase.Opt_DHCPv6_StatusCode"})) {
#$optionstr .= "<B>#StatusCode Option</B><BR> StatusCode= ".$$frame{"$optbase\.Opt_DHCPv6_StatusCode\.StatusCode"}." ";
#$optionstr .= get_statuscode_string($$frame{"$optbase\.Opt_DHCPv6_StatusCode\.StatusCode"})." <BR>";
#}
#while(defined($$frame{"$optbase$count"})){
#vLogHTML("optbase = $optbase <BR>");
#vLogHTML("optbase$coutn = $optbase$count");
#my $iaaddrnum = 2;
#my $optiaaddr = "$optbase.Opt_DHCPv6_IA_Address$iaaddrnum";
# while(defined($$frame{"$optiaaddr"})){
# $optionstr .= "<B>#IA_Addr Option $iaaddrnum</B><BR>";
# $optionstr .= "Addr= ".$$frame{"$optiaaddr\.Address"}."<BR>";
# $optionstr .= "PreferredLifetime= ".$$frame{"$optiaaddr\.PreferredLifetime"}."<BR>";
# $optionstr .= "ValidLifetime= ".$$frame{"$optiaaddr\.ValidLifetime"}."<BR>";
# if(defined($$frame{"$optiaaddr\.Opt_DHCPv6_StatusCode"})){
# $optionstr .= "<B>#StatusCode Option</B><BR>";
# $optionstr .= "StatusCode= ".$$frame{"$optiaaddr\.Opt_DHCPv6_StatusCode\.StatusCode"}." ";
# $optionstr .= get_statuscode_string($$frame{"$optiaaddr\.Opt_DHCPv6_StatusCode\.StatusCode"})." <BR>";
# }
# $iaaddrnum++;
#}
if(defined($$frame{"$optbase.Opt_DHCPv6_StatusCode"})) {
$optionstr .= "<B>#StatusCode Option</B><BR> StatusCode= ".$$frame{"$optbase\.Opt_DHCPv6_StatusCode\.StatusCode"}." ";
$optionstr .= get_statuscode_string($$frame{"$optbase\.Opt_DHCPv6_StatusCode\.StatusCode"})." <BR>";
}
my $count =2;
#vLogHTML("$optbase$count");
while(defined($$frame{"$optbase$count"})){
#vLogHTML("optbase = $optbase <BR>");
#vLogHTML("optbase$coutn = $optbase$count");
$optionstr .= "<B>Option $count"."</B><BR>";
$optionstr .= "Identifier= ".$$frame{"$optbase$count\.Identifier"}."<BR>";
$optionstr .= "T1= ".$$frame{"$optbase$count\.Time1"}."<BR>";
$optionstr .= "T2= ".$$frame{"$optbase$count\.Time2"}."<BR>";
if(defined($$frame{"$optbase$count.Opt_DHCPv6_IA_Address"})) {
$optionstr .= "<B>#IA_Addr Option</B><BR>";
$optionstr .= "Addr= ".$$frame{"$optbase$count\.Opt_DHCPv6_IA_Address\.Address"}."<BR>";
$optionstr .= "PreferredLifetime= ".$$frame{"$optbase$count\.Opt_DHCPv6_IA_Address\.PreferredLifetime"}."<BR>";
$optionstr .= "ValidLifetime= ".$$frame{"$optbase$count\.Opt_DHCPv6_IA_Address\.ValidLifetime"}."<BR>";
if(defined($$frame{"$optbase$count.Opt_DHCPv6_IA_Address.Opt_DHCPv6_StatusCode"})) {
$optionstr .= "<B>#StatusCode Option</B><BR>";
$optionstr .= "StatusCode= ".$$frame{"$optbase$count\.Opt_DHCPv6_IA_Address\.Opt_DHCPv6_StatusCode\.StatusCode"}." ";
$optionstr .= get_statuscode_string($$frame{"$optbase$count\.Opt_DHCPv6_IA_Address\.Opt_DHCPv6_StatusCode\.StatusCode"})." <BR>";
}
}
if(defined($$frame{"$optbase$count.Opt_DHCPv6_StatusCode"})) {
$optionstr .= "<B>#StatusCode Option</B><BR> StatusCode= ".$$frame{"$optbase$count\.Opt_DHCPv6_StatusCode\.StatusCode"}." ";
$optionstr .= get_statuscode_string($$frame{"$optbase$count\.Opt_DHCPv6_StatusCode\.StatusCode"})." <BR>";
}
$count++;
}
}
# Opt_DHCPv6_IA_TA
if ("Opt_DHCPv6_IA_TA" eq $option_defs{$_}) {
$optionstr .= "Identifier= ".$$frame{"$optbase\.Identifier"}."<BR>";
if(defined($$frame{"$optbase.Opt_DHCPv6_IA_Address"})) {
$optionstr .= "<B>#IA_Addr Option</B><BR>";
$optionstr .= "Addr= ".$$frame{"$optbase\.Opt_DHCPv6_IA_Address\.Address"}."<BR>";
$optionstr .= "PreferredLifetime= ".$$frame{"$optbase\.Opt_DHCPv6_IA_Address\.PreferredLifetime"}."<BR>";
$optionstr .= "ValidLifetime= ".$$frame{"$optbase\.Opt_DHCPv6_IA_Address\.ValidLifetime"}."<BR>";
if(defined($$frame{"$optbase.Opt_DHCPv6_IA_Address.Opt_DHCPv6_StatusCode"})) {
$optionstr .= "<B>#StatusCode Option</B><BR>";
$optionstr .= "StatusCode= ".$$frame{"$optbase\.Opt_DHCPv6_IA_Address\.Opt_DHCPv6_StatusCode\.StatusCode"}." ";
$optionstr .= get_statuscode_string($$frame{"$optbase\.Opt_DHCPv6_IA_Address\.Opt_DHCPv6_StatusCode\.StatusCode"})." <BR>";
}
}
if(defined($$frame{"$optbase\.Opt_DHCPv6_StatusCode"})) {
$optionstr .= "<B>#StatusCode Option</B><BR> StatusCode= ".$$frame{"$optbase\.Opt_DHCPv6_StatusCode\.StatusCode"};
}
}
# Opt_DHCPv6_IA_PD
if ("Opt_DHCPv6_IA_PD" eq $option_defs{$_}) {
$optionstr .= "Identifier= ".$$frame{"$optbase\.Identifier"}."<BR>";
$optionstr .= "T1= ".$$frame{"$optbase\.Time1"}."<BR>";
$optionstr .= "T2= ".$$frame{"$optbase\.Time2"}."<BR>";
if(defined($$frame{"$optbase.Opt_DHCPv6_IA_Prefix#"})) {
my $count = $$frame{"$optbase.Opt_DHCPv6_IA_Prefix#"};
for(my $i=1; $i<=$count;$i++){
$optionstr .= "<B>#IA_Prefix Option $i</B><BR>";
if(1 == $i){
$optionstr .= "Prefix= ".$$frame{"$optbase\.Opt_DHCPv6_IA_Prefix\.Prefix"}."<BR>";
$optionstr .= "Prefix Length= ".$$frame{"$optbase\.Opt_DHCPv6_IA_Prefix\.PrefixLength"}."<BR>";
$optionstr .= "PreferredLifetime= ".$$frame{"$optbase\.Opt_DHCPv6_IA_Prefix\.PreferredLifetime"}."<BR>";
$optionstr .= "ValidLifetime= ".$$frame{"$optbase\.Opt_DHCPv6_IA_Prefix\.ValidLifetime"}."<BR>";
if(defined($$frame{"$optbase.Opt_DHCPv6_IA_Prefix.Opt_DHCPv6_StatusCode"})) {
$optionstr .= "<B>#StatusCode Option</B><BR>";
$optionstr .= "StatusCode= ".$$frame{"$optbase\.Opt_DHCPv6_IA_Prefix\.Opt_DHCPv6_StatusCode\.StatusCode"}." ";
$optionstr .= get_statuscode_string($$frame{"$optbase\.Opt_DHCPv6_IA_Prefix\.Opt_DHCPv6_StatusCode\.StatusCode"})." <BR>";
}
}
else{
$optionstr .= "Prefix= ".$$frame{"$optbase\.Opt_DHCPv6_IA_Prefix$i\.Prefix"}."<BR>";
$optionstr .= "Prefix Length= ".$$frame{"$optbase\.Opt_DHCPv6_IA_Prefix$i\.PrefixLength"}."<BR>";
$optionstr .= "PreferredLifetime= ".$$frame{"$optbase\.Opt_DHCPv6_IA_Prefix$i\.PreferredLifetime"}."<BR>";
$optionstr .= "ValidLifetime= ".$$frame{"$optbase\.Opt_DHCPv6_IA_Prefix$i\.ValidLifetime"}."<BR>";
if(defined($$frame{"$optbase.Opt_DHCPv6_IA_Prefix$i.Opt_DHCPv6_StatusCode"})) {
$optionstr .= "<B>#StatusCode Option</B><BR>";
$optionstr .= "StatusCode= ".$$frame{"$optbase\.Opt_DHCPv6_IA_Prefix$i\.Opt_DHCPv6_StatusCode\.StatusCode"}." ";
$optionstr .= get_statuscode_string($$frame{"$optbase\.Opt_DHCPv6_IA_Prefix$i\.Opt_DHCPv6_StatusCode\.StatusCode"})." <BR>";
}
}
}
}
if(defined($$frame{"$optbase\.Opt_DHCPv6_StatusCode"})) {
$optionstr .= "<B>#StatusCode Option</B> <BR>StatusCode= ".$$frame{"$optbase\.Opt_DHCPv6_StatusCode\.StatusCode"};
}
}
# Opt_DHCPv6_OptionRequest
if ("Opt_DHCPv6_OptionRequest" eq $option_defs{$_}) {
$optionstr .= "OptionCode = ".$$frame{"$optbase.OptionCode"}." ".get_optname_string($$frame{"$optbase.OptionCode"})."<BR>";
for (my $n=0; $n<20; $n++) {
if (defined ($$frame{"$optbase.OptionCode_$n"})) {
$optionstr .= "OptionCode = ".$$frame{"$optbase.OptionCode_$n"}." ".get_optname_string($$frame{"$optbase.OptionCode_$n"})."<BR>";
}
}
}
# Opt_DHCPv6_Preference
if ("Opt_DHCPv6_Preference" eq $option_defs{$_}) {
$optionstr .= "Preference = ".$$frame{"$optbase\.Preference"}."<BR>";
}
# Opt_DHCPv6_ElapsedTime
if ("Opt_DHCPv6_ElapsedTime" eq $option_defs{$_}) {
$optionstr .= "Time = ".$$frame{"$optbase\.Time"}."<BR>";
}
# Opt_DHCPv6_RelayMessage
if ("Opt_DHCPv6_RelayMessage" eq $option_defs{$_}) {
$optionstr = "";
}
# Opt_DHCPv6_Authentication
if ("Opt_DHCPv6_Authentication" eq $option_defs{$_}) {
$optionstr .= "Protocol = ".$$frame{"$base\.Opt_DHCPv6_Authentication\.Protocol"}."<BR>";
$optionstr .= "Algorithm = ".$$frame{"$base\.Opt_DHCPv6_Authentication\.Algorithm"}."<BR>";
$optionstr .= "ReplayDetection = ".$$frame{"$base\.Opt_DHCPv6_Authentication\.ReplayDetection"}."<BR>";
$optionstr .= "<B>Authentication information</B>:"."<BR>";
if ($$frame{"$base\.Opt_DHCPv6_Authentication\.Protocol"} eq '2'){
if(defined($$frame{"$base\.Opt_DHCPv6_Authentication\.DHCPv6_Auth_Delayed\.Realm"})){
$optionstr .= "<DD>DHCP realm = ".$$frame{"$base\.Opt_DHCPv6_Authentication\.DHCPv6_Auth_Delayed\.Realm"}."<BR>";
$optionstr .= "<DD>key ID = ".$$frame{"$base\.Opt_DHCPv6_Authentication\.DHCPv6_Auth_Delayed\.Identifier"}."<BR>";
$optionstr .= "<DD>HMAC-MD5 = ".$$frame{"$base\.Opt_DHCPv6_Authentication\.DHCPv6_Auth_Delayed\.Authenticator"}."<BR>";
}
else{
$optionstr .= "<DD><B>Nothing</B>"."<BR>";
}
}
elsif ($$frame{"$base\.Opt_DHCPv6_Authentication\.Protocol"} eq '3'){
$optionstr .= "<DD>Type = ".$$frame{"$base\.Opt_DHCPv6_Authentication\.DHCPv6_Auth_ReconfigureKey\.Type"}."<BR>";
$optionstr .= "<DD>Value = ".$$frame{"$base\.Opt_DHCPv6_Authentication\.DHCPv6_Auth_ReconfigureKey\.data"}."<BR>";
}
}
# Opt_DHCPv6_ServerUnicast
if ("Opt_DHCPv6_ServerUnicast" eq $option_defs{$_}) {
$optionstr .= "Address= ".$$frame{"$base\.Opt_DHCPv6_ServerUnicast\.Address"}."<BR>";
}
# Opt_DHCPv6_StatusCode
if ("Opt_DHCPv6_StatusCode" eq $option_defs{$_}) {
$optionstr = "StatusCode= ".$$frame{"$optbase\.StatusCode"}." ";
$optionstr .= get_statuscode_string($$frame{"$optbase\.StatusCode"})." <BR>";
for ($i=2; $i<5; $i++) {
if (defined ($$frame{"$optbase$i\.StatusCode"})) {
$optionstr .= "StatusCode= ".$$frame{"$optbase$i\.StatusCode"}." ";
$optionstr .= get_statuscode_string($$frame{"$optbase$i\.StatusCode"})." <BR>";
}
}
}
# Opt_DHCPv6_RapidCommit
if ("Opt_DHCPv6_RapidCommit" eq $option_defs{$_}) {
$optionstr = "*";
}
# Opt_DHCPv6_UserClass or Opt_DHCPv6_VendorClass
if (("Opt_DHCPv6_UserClass" eq $option_defs{$_}) || ("Opt_DHCPv6_VendorClass" eq $option_defs{$_})) {
# $optionstr .= "data = ".$$frame{'"$optbase"."$option_defs{$_}".".data"'}."<BR>";
}
# Opt_DHCPv6_VendorSpecificInfo
if ("Opt_DHCPv6_VendorSpecificInfo" eq $option_defs{$_}) {
$optionstr .= "EnterpriseNumber = ".$$frame{"$base\.Opt_DHCPv6_VendorSpecificInfo\.EnterpriseNumber"}."<BR>";
# $optionstr .= "data = ".$$frame{"$optbase\.Opt_DHCPv6_VendorSpecificInfo\.data"}."<BR>";
}
# Opt_DHCPv6_IID
if ("Opt_DHCPv6_IID" eq $option_defs{$_}) {
$optionstr .= "Identifier = ".$$frame{"$optbase\.Identifier"}."<BR>";
}
# Opt_DHCPv6_ReconfigureMessage
if ("Opt_DHCPv6_ReconfigureMessage" eq $option_defs{$_}) {
$optionstr .= "Type = ".$$frame{"$optbase\.Type"}."<BR>";
}
# Opt_DHCPv6_ReconfigureAccept
if ("Opt_DHCPv6_ReconfigureAccept" eq $option_defs{$_}) {
$optionstr .= "<BR>";
}
# Opt_DHCPv6_DNS_Servers
if ("Opt_DHCPv6_DNS_Servers" eq $option_defs{$_}) {
$optionstr = "DNS = ".$$frame{"$optbase\.Address"}."<BR>";
}
# Opt_DHCPv6_ANY
if ("Opt_DHCPv6_ANY" eq $option_defs{$_}) {
$optionstr .= "Code = ".$$frame{"$optbase\.Code"};
}
# Transaction Identifier
if ("Identifier" eq $option_defs{$_}) {
$optionstr .= "Identifier = ".$$frame{"$base".".Identifier"};
}
vLogHTML("<tr><td><B>$option_defs{$_}</B></td><td>$optionstr</td></tr>");
}
vLogHTML("</table>");
}
#--------------------------------------------------------------#
# get_value($$$;$) #
# #
# Notes: #
# get the value from message #
# Input: #
# $frame #
# $option #
# $field #
# $suboption #
# return: #
# $content{"ret"} #
# 0: pass #
# 1: fail #
# $content{"$field"} #
# content of designated field #
# eg. #
# get_value(\%ref,"Opt_DHCPv6_ElapsedTime","Time"); #
#--------------------------------------------------------------#
sub get_value($$$;$){
my ($frame,$option,$field,$suboption) = @_;
my $base = undef;
my $optbase = undef;
my %content = undef;
foreach(keys %dhcp6_messages) {
$base = $dhcp6_messages{$_};
if (defined($$frame{"$base"})){
last;
}
$base = "";
}
# print "\n\nbase = $base";
if ($base eq ""){
$content{"ret"}= 1;
return %content;
}
$optbase = "$base"."."."$option";
# print "\n\noptbase = $optbase";
if(defined $suboption){
$optbase = "$optbase"."."."$suboption";
}
if(!defined($$frame{"$optbase"})){
$content{"ret"}= 1;
return %content;
}
$optbase = "$optbase".".".$field;
# print "\n\noptbase = $optbase";
if(!defined ($$frame{$optbase})){
$content{"ret"}= 1;
return %content;
}
$content{"$field"} = $$frame{"$optbase"};
# print "\n content field = $content{$field} ";
$content{"ret"} = 0;
return %content;
}
sub gen_cpp_inforeq($){
my ($frame) = @_;
my $base;
foreach(keys %dhcp6_messages) {
$base = $dhcp6_messages{$_};
if (defined($$frame{"$base"})){
last;
}
$base = "";
}
print "\n";
print "base = $base \n ";
print "\n";
my $optstr = "";
my $cppstr = "";
if(defined($$frame{"$base.Opt_DHCPv6_CID.DHCPv6_DUID_LLT_Ether.LinkLayerAddress"}))
{
$optstr = $$frame{"$base.Opt_DHCPv6_CID.DHCPv6_DUID_LLT_Ether.LinkLayerAddress"};
print "\n LinkLayerAddress = $optstr \n ";
$cppstr = " -D\'NUT_DUID_MAC_ADDR=ether(\"$optstr\")\' ";
}
if(defined($$frame{"$base.Opt_DHCPv6_CID.DHCPv6_DUID_LLT_Ether.Time"}))
{
$optstr = $$frame{"$base.Opt_DHCPv6_CID.DHCPv6_DUID_LLT_Ether.Time"};
print "\n Time = $optstr \n";
$cppstr .= " -D\'NUT_DUID_TIME=$optstr\' ";
}
# when receive DUID Code =1 and Hareware type is not 1
if(defined($$frame{"$base.Opt_DHCPv6_CID.DHCPv6_DUID_LLT_ANY.HardwareType"}))
{
$optstr = $$frame{"$base.Opt_DHCPv6_CID.DHCPv6_DUID_LLT_ANY.HardwareType"};
$cppstr .= " -D\'NUT_DUID_HARDWARE_TYPE = $optstr\' ";
}
if(defined($$frame{"$base.Opt_DHCPv6_CID.DHCPv6_DUID_LLT_ANY.LinkLayerAddress"}))
{
$optstr = $$frame{"$base.Opt_DHCPv6_CID.DHCPv6_DUID_LLT_ANY.LinkLayerAddress"};
$cppstr .= " -D\'NUT_DUID_MAC_ADDR=hexstr(\"$optstr\")\' ";
}
if(defined($$frame{"$base.Opt_DHCPv6_CID.DHCPv6_DUID_LLT_ANY.Time"}))
{
$optstr = $$frame{"$base.Opt_DHCPv6_CID.DHCPv6_DUID_LLT_ANY.Time"};
$cppstr .= " -D\'NUT_DUID_TIME=$optstr\' ";
}
if(defined($$frame{"$base.Identifier"}))
{
$optstr = $$frame{"$base.Identifier"};
$cppstr .= " -D\'ID_REP=$optstr\' ";
}
return $cppstr;
}
#--------------------------------------------------------------#
# getElapsedtime($) #
# #
# Notes: #
# get the Elsapse time from message #
# Input: #
# $frame #
# return: #
# eg. getElapsedtime(\%frame) #
#--------------------------------------------------------------#
sub getElapsedtime($){
my ($frame) = @_;
my $pktcount = 0;
my $time = 0;
# $pktcount = $$frame{"recvCount"};
# print"\npkt count is $pktcount\n" if($pktcount ne 1);
# $time = $$frame{"recvTime$pktcount"};
# return $time;
my %content = get_value($frame,"Opt_DHCPv6_ElapsedTime","Time");
my $time = $content{"Time"};
# $time = (($time>>8)&0x00ff)+(($time<<8)&0xff00);
$time = $time/100;
return $time;
}
#--------------------------------------------------------------#
# parse_relay_message($frame) #
# #
# Notes: #
# parse and show DHCPv6 Relay Messages #
# #
#--------------------------------------------------------------#
sub parse_relay_message($) {
my $frame_ref = $_[0];
my $strBaseRelayForwardIndex = "Frame_Ether.Packet_IPv6.Upp_UDP.Udp_DHCPv6_RelayForward";
my $strBaseRelayReplyIndex = "Frame_Ether.Packet_IPv6.Upp_UDP.Udp_DHCPv6_RelayReply";
my $strBaseIndex = undef;
#Relay-forward message
if(defined ($$frame_ref{$strBaseRelayForwardIndex})){
message_output($frame_ref,"Relay-forward",$strBaseRelayForwardIndex);
$strBaseIndex .= $strBaseRelayForwardIndex.".Opt_DHCPv6_RelayMessage";
}
elsif(defined($$frame_ref{$strBaseRelayReplyIndex})){
message_output($frame_ref,"Relay-reply",$strBaseRelayReplyIndex);
$strBaseIndex = $strBaseRelayReplyIndex.".Opt_DHCPv6_RelayMessage";
}
else{
return;
}
if(defined($$frame_ref{$strBaseIndex})){
message_output($frame_ref,"Relay Message option",$strBaseIndex);
}
}
#--------------------------------------------------------------#
# #
# #
# Notes: #
# Exit value process sub-route #
# #
#--------------------------------------------------------------#
################################################################
# dhcpExitPass()
################################################################
sub dhcpExitPass() {
#======================================================================
vLogHTML("<FONT SIZE=3>*** Target test finish ***<FONT><BR>");
#======================================================================
dhcpReset();
vLogHTML('<B>OK</B><BR>');
exit $V6evalTool::exitPass;
}
################################################################
# dhcpExitIgnore()
# Exit with value Ignore this test
################################################################
sub dhcpExitIgnore() {
exit $V6evalTool::exitIgnore;
}
################################################################
# dhcpExitNS()
# Exit with value "Not support"
################################################################
sub dhcpExitNS() {
# dhcpReset();
vLogHTML("This test is not supported by NUT now<BR>");
exit $V6evalTool::exitNS;
}
################################################################
# dhcpExitSkip()
# Exit with value "skip"
################################################################
sub dhcpExitSkip() {
vLogHTML("This test is skipped<BR>");
exit $V6evalTool::exitSkip;
}
################################################################
# dhcpExitError()
# Note:
# Exit with error message.
################################################################
sub dhcpExitError($) {
my ($msg) = @_;
vLogHTML("<FONT COLOR=\"#FF0000\">NG: <B>$msg</B> </FONT><BR>");
dhcpReset();
exit $V6evalTool::exitFail;
}
################################################################
# dhcpExitFail(;$msg)
# Note:
# The test is failed.
# Only the error message "NG" is displayed
################################################################
sub dhcpExitFail(;$) {
my ($msg) = @_;
if(defined($msg)){
$msg = ": " . $msg;
}
else{
$msg = "";
}
vLogHTML("<FONT COLOR=\"#FF0000\">NG$msg</FONT><BR>");
dhcpReset();
exit $V6evalTool::exitFail;
}
################################################################
# dhcpReset()
# Reset the test environment to the original status
# Now it Only use for Server!!!!
# can not use it in initial test!!!
#
################################################################
sub dhcpReset() {
my $count = 0;
my $IFName = undef;
my $Base_ref = undef;
my $ret = undef;
#only used for server or relay agent;
if(defined($V6evalTool::opt_pkt))
{
my $pktfilename = $V6evalTool::opt_pkt;
if($pktfilename =~ /S_RFC/){
$Base_ref = $NUT_Server_Config_ref;
vLogHTML("DHCPv6 Server stop<BR>");
$ret = vRemote("dhcp6s.rmt", "stop","");
$MAXIFCOUNT = 0;
}
elsif($pktfilename =~ /R_RFC/){
$Base_ref = $NUT_Relay_Config_ref;
vLogHTML("DHCPv6 Relay agent stop<BR>");
$ret = vRemote("dhcp6r.rmt", "stop", "");
}
elsif($pktfilename =~ /C_RFC/){
vLogHTML("DHCPv6 Client stop<BR>");
$ret = vRemote("dhcp6c.rmt", "stop", "");
return;
}
}
else{
return;
}
if(!defined($Base_ref)){
return;
}
#Stop the interface of TN.
while($MAXIFCOUNT >= $count){
$IFName = sprintf("Link%d",$count);
if(defined ($V6evalTool::TnDef{"$IFName"})){
my ($if,$add,$length) = ($$Base_ref{"if_nut".$count},
$$Base_ref{"if_add".$count},
$$Base_ref{"if_length".$count});
#vLogHTML("if $if add $add length $length ");
if ((defined $if)&& (defined $add) && (defined $length)){
vRemote('manualaddrconf.rmt',"if=$if","addr=$add","len=$length","type=delete");
}
vStop($IFName);
vLogHTML("Stop $IFName<BR>");
}
else{
last;
}
$count++;
}
}
#---------------------------------------------------------------#
# dhcpRelayInit(\$Relay_Config_Ref)
# Initial the DHCP server
# Note:
# Only use for the NUT type Relay agent!!!!
# now only support 1 init_opcode!!!
# ---------------Sample-----------------------------------------
#initial NUT config parameters,
#my %NUT_Relay_Config = (
# 'if_nut0'=> "$V6evalTool::NutDef{Link0_device}",
# 'if_nut1' => "$V6evalTool::NutDef{Link1_device}",
# 'if_add0' => "fe80::200:ff:fe00:a4a4",
# 'if_add1' => "fe80::200:ff:fe00:a5a5",
# 'if_length0' => "64",
# 'if_length1' => "64",
# 'if_type0'=> "unicast",
# 'if_type1'=> "unicast",
# 'init_opcode' => "vRemote(\"dhcp6s.rmt\", \"start\",\"link0=$V6evalTool::NutDef{Link0_device}\",\"startaddr=3ffe:501:ffff:100::10\",\"endaddr=3ffe:501:ffff:100::11\")"
#);
#
#---------------------------------------------------------------#
sub dhcpRelayInit($){
$NUT_Relay_Config_ref = $_[0];
my $type=$V6evalTool::NutDef{Type};
if($type ne 'router') {
vLogHTML("NG: The test of Relay-agent only can be run on the router!<BR>");
vLogHTML("Please check the NUT setting file.<BR>");
exit $V6evalTool::exitNS;
}
my $cpp .= '-D LINK1';
vCPP($cpp);
dhcpSvrRelayCommonInit($NUT_Relay_Config_ref);
return;
}
#---------------------------------------------------------------#
# dhcpSvrInit(\$Server_Config_Ref)
# Initial the DHCP server
# Note:
# Only use for the NUT type Server!!!!
# now only support 1 init_opcode!!!
# ---------------Sample-----------------------------------------
#my %NUT_Server_Config = {
# "if_nut0" => $V6evalTool::NutDef{Link0_device},
# "if_add0" => "fe80::200:ff:fe00:a1a1",
# "if_length0" => "64",
# "if_type0"=> "unicast",
# "init_opcode" =>
#};
#---------------------------------------------------------------#
sub dhcpSvrInit($){
$NUT_Server_Config_ref = $_[0];
if($INITIAL_RA){
vSend("Link0", 'ra_server2_to_all_MO_1');
vRecv("Link0", 3, 0, 0, 'dadns_nutga');
vSleep(3);
}
dhcpSvrRelayCommonInit($NUT_Server_Config_ref);
return ;
}
sub dhcpSvrInitS($){
$NUT_Server_Config_ref = $_[0];
if($INITIAL_RA){
vSend("Link0", 'ra_server2_to_all_addr_assign');
vRecv("Link0", 3, 0, 0, 'dadns_nutga');
vSleep(3);
}
dhcpSvrRelayCommonInit($NUT_Server_Config_ref);
return ;
}
#---------------------------------------------------------------#
# dhcpSvrRelayCommonInit($Config_Ref)
# Initial the DHCP NUT
# Note:
#---------------------------------------------------------------#
sub dhcpSvrRelayCommonInit($){
my $Base_ref = $_[0];
my $count = 0;
my ($if,$add,$length,$type,$opcode) =(undef,undef,undef,undef);
while($MAXIFCOUNT >= $count){
($if,$add,$length,$type) = ($$Base_ref{"if_nut".$count},
$$Base_ref{"if_add".$count},
$$Base_ref{"if_length".$count},
$$Base_ref{"if_type".$count});
if ((defined $if)&& (defined $add) && (defined $length)&& (defined $type) ){
# set the address of DHCPv6 Server
SetNUTAddr($if,$add,$length,$type);
}
$count++;
}
# start NUT
$opcode = $$Base_ref{"init_opcode"};
my $ret = undef;
if(defined($opcode)){
vLogHTML($opcode);
#$ret = eval($opcode);
$opcode =~ s/\"//g;
if ($opcode =~ /vRemote\((.*)\)/){
my $strOption = $1;
my @cmdOp = split(/,/,$strOption);
my $Filename = shift @cmdOp;
my $opts = shift @cmdOp;
$ret = vRemote($Filename,$opts,@cmdOp);
# For output debug messages;
# print $@;
# vSleep(1);
}
}
if($ret != 0) {
vLogHTML('<FONT COLOR="#FF0000">Cannot Initialize NUT.</FONT><BR>');
dhcpExitFail();
};
#Begin capture;
$count = 0;
while($MAXIFCOUNT >= $count){
if(defined($$Base_ref{"if_nut".$count})){
my $tnif = "Link$count";
vCapture($tnif);
vClear($tnif);
}
$count ++;
}
return;
}
#--------------------------------------------------------------#
# ChkFuncSupport(\$Fuction_type) #
# #
# Notes: #
# check if the function has been support #
# The function code are listed in dhcpv6_conf. #
# #
# Input: Function type #
#--------------------------------------------------------------#
sub ChkFuncSupport($){
my ($config_param) = @_;
my $param = ${$DHCPv6_config::{$config_param}};
if($param){
return 0;
}
return 1;
}
#--------------------------------------------------------------#
# ChkConfig(\$Config_Param) #
# #
# Notes: #
# check if the configration parametor is defined #
# The function parametors are listed in dhcpv6_conf. #
# #
# Input: Function type #
#--------------------------------------------------------------#
sub ChkConfig($){
my ($config_param) = @_;
my $param = ${$DHCPv6_config::{$config_param}};
if($param){
return $param;
}
return 1;
}
#--------------------------------------------------------------#
#Ascii2Hex() #
# Notes: #
# Exchange ascii to binary #
# #
# Input: ascii #
#--------------------------------------------------------------#
sub
Ascii2Hex($)
{
my ($ascii_hex) = @_;
$ascii_hex =~ s/(.)/unpack("H2", $1)/ego;
# vLogHTML("ASCII to HEX: $ascii_hex<BR>");
return($ascii_hex);
}
#--------------------------------------------------------------#
#Ascii2Base64() #
# Notes: #
# Encode ascii to base64 #
# #
# Input: ascii #
#--------------------------------------------------------------#
sub
Ascii2Base64($)
{
my ($ascii_base) = @_;
$ascii_base = encode_base64($ascii_base, '');
# vLogHTML("ASCII to BASE64: $ascii_base<BR>");
return($ascii_base);
}
#--------------------------------------------------------------#
#SharedSecretKeyCheck() #
# Notes: #
# Shared secret key check to cover dependency #
# of implementation #
# Input: #
# 1st: secret key type #
# 2nd: ascii shared secret key #
# Return: #
# value: depend on implementation #
# Now support only MIME64(BASE64) #
#--------------------------------------------------------------#
sub
SharedSecretKeyCheck($$){
my ($secret_type, $secret_key) = @_;
if ($secret_type eq 'MIME64'){
$secret_key = Ascii2Base64($secret_key);
}
return($secret_key);
}
#--------------------------------------------------------------#
#ReplayDetectCounter() #
# Notes: #
# Increment replay detection field #
# #
# Input: Hex replay detection counter #
#--------------------------------------------------------------#
sub
ReplayDetectCounter($)
{
my ($hex_counter) = @_;
my ($bitdata, $i_bitdata, $replay_counter) = undef;
$bitdata = unpack("B64", pack("H*", $hex_counter));
$i_bitdata = $bitdata | '0000000000000000000000000000000000000000000000000000000000000001';
$replay_counter = unpack("H*", pack("B64", $i_bitdata));
vLogHTML("Increment replay detection field: $replay_counter<BR>");
return($replay_counter);
}
#--------------------------------------------------------------#
# checkDUID(\$frame,$OptionTYpe,$Type) #
# #
# Notes: #
# check the format of DUID,only use for check msgs #
# include sid or cid #
# In: #
# \$frame: data frame #
# $OptionType:the type of ID option $CMP_SID,$CMP_CID #
# $Type:DUID's type 1,LLT 2,EN 3,LL #
#Return: #
# 0:success #
# 1:NG #
#--------------------------------------------------------------#
sub check_DUID($$$){
my ($refFrame,$optype,$duidtype)=@_;
my $optbase = "";
#check whether the message has the option
return 1 if (0 != options_exist($refFrame,$optype));
#obtain base index
my $temp;
foreach(keys %dhcp6_messages) {
$temp = $dhcp6_messages{$_};
if (defined($$refFrame{$temp})){
$optbase = "$temp"."."."$option_defs{$optype}";
last;
}
}
if("" eq $optbase){
return 1;
}
my $duidbase = "$optbase"."."."$duid_types{$duidtype}";
return 1 if(!defined($$refFrame{$duidbase}));
my $duidValIndex = undef;
if (1 == $duidtype){
$duidValIndex = "$duidbase"."."."Type";
my $duidHardtypeIndex = "$duidbase"."."."HardwareType";
my $timeIndex = "$duidbase"."."."Time";
my $LLAIndex = "$duidbase"."."."LinkLayerAddress";
if((1 == $$refFrame{$duidValIndex}) &&
(defined( $$refFrame{$duidHardtypeIndex}) )&&
(defined($$refFrame{$timeIndex}))&&
(defined($$refFrame{$LLAIndex}))){
vLogHTML("DUID type:<FONT COLOR='#F25B00'>$duid_types{$duidtype}</FONT><br>");
return 0;
}
}
elsif (2 == $duidtype) {
$duidValIndex = "$duidbase"."."."Type";
my $duidIDIndex = "$duidbase"."."."Identifier";
my $duidEnIndex = "$duidbase"."."."EnterpriseNumber";
if((2 == $$refFrame{$duidValIndex}) &&
(defined($$refFrame{$duidEnIndex})) &&
(defined($$refFrame{$duidIDIndex}))){
vLogHTML("DUID type:<FONT COLOR='#F25B00'>$duid_types{$duidtype}</FONT><br>");
return 0;
}
}
elsif (3 == $duidtype) {
$duidValIndex = "$duidbase"."."."Type";
my $duidHardtypeIndex = "$duidbase"."."."HardwareType";
my $duidLLAIndex = "$duidbase"."."."LinkLayerAddress";
if((3 == $$refFrame{$duidValIndex}) &&
(defined($$refFrame{$duidHardtypeIndex})) &&
(defined($$refFrame{$duidLLAIndex}))){
vLogHTML("DUID type:<FONT COLOR='#F25B00'>$duid_types{$duidtype}</FONT><br>");
return 0;
}
}
return 1;
}
#--------------------------------------------------------------#
# ck_IAoptions($frame1, $frame2,$count) #
# #
# Notes: #
# check the IA options in 2 frames, #
# if the number and ID is same,pass #
# please use it after options_exit #
# Only use for 1 message packet #
# #
# Input: #
# 2 references for the frames need to compare #
# IA count number #
# EXIST: return 0 #
# NOT EXIST: return 1 #
#--------------------------------------------------------------#
sub ck_IAoptions($$$) {
my ($frame1,$frame2,$count) = @_;
if(!defined($frame1) || !defined($frame2)){
vLogHTML("NULL frame has been used!");
return 1;
}
my ($ret1,$basStr1) = getMsgTypeLocStr($frame1);
my ($ret2,$basStr2) = getMsgTypeLocStr($frame2);
if($ret1 || $ret2){
vLogHTML("Invalid Message!");
return 1;
}
# Sample: Frame_Ether.Packet_IPv6.Upp_UDP.Udp_DHCPv6_Solicit.Opt_DHCPv6_IA_NA.Opt_DHCPv6_IA_NA2
my ($ID1,$ID2)=("","");
# attention, replace 10 to constant varible at the following work stage.
# Max. value of IA options
return 0 if (1== $count);
while($count>1 ){
#vLogHTML("$basStr1.Opt_DHCPv6_IA_NA$count.Identifier");
$ID1 = $$frame1{"$basStr1.Opt_DHCPv6_IA_NA$count.Identifier"};
$ID2 = $$frame2{"$basStr2.Opt_DHCPv6_IA_NA$count.Identifier"};
if((!defined($ID1) || !defined($ID2))){
$ID1 = $$frame1{"$basStr1.Opt_DHCPv6_IA_TA$count.Identifier"};
$ID2 = $$frame2{"$basStr2.Opt_DHCPv6_IA_TA$count.Identifier"};
if((!defined($ID1) || !defined($ID2))){
vLogHTML("<B>Can not found specific number of IA options</B><BR>");
return 1;
}
}
if($ID1 != $ID2){
vLogHTML("<B>The value of IA option is un-expected!</B><BR>");
return 1;
}
$count--;
}
return 0;
}
#--------------------------------------------------------------#
# ck_IAPDoptions($frame1, $frame2,$count) #
# #
# Notes: #
# check the IA_PD options in 2 frames, #
# if the number and ID is same,pass #
# please use it after options_exit #
# Only use for 1 message packet #
# #
# Input: #
# 2 references for the frames need to compare #
# IA_PD count number #
# EXIST: return 0 #
# NOT EXIST: return 1 #
#--------------------------------------------------------------#
sub ck_IAPDoptions($$$) {
my ($frame1,$frame2,$count) = @_;
if(!defined($frame1) || !defined($frame2)){
vLogHTML("NULL frame has been used!");
return 1;
}
my ($ret1,$basStr1) = getMsgTypeLocStr($frame1);
my ($ret2,$basStr2) = getMsgTypeLocStr($frame2);
if($ret1 || $ret2){
vLogHTML("Invalid Message!");
return 1;
}
# Sample: Frame_Ether.Packet_IPv6.Upp_UDP.Udp_DHCPv6_Solicit.Opt_DHCPv6_IA_PD2
my ($ID1,$ID2)=("","");
# attention, replace 10 to constant varible at the following work stage.
# Max. value of IA options
return 0 if (1== $count);
while($count>1 ){
#vLogHTML("$basStr1.Opt_DHCPv6_IA_PD$count.Identifier");
$ID1 = $$frame1{"$basStr1.Opt_DHCPv6_IA_PD$count.Identifier"};
$ID2 = $$frame2{"$basStr2.Opt_DHCPv6_IA_PD$count.Identifier"};
if((!defined($ID1) || !defined($ID2))){
vLogHTML("<B>Can not found special number of IA_PD options</B><BR>");
return 1;
}
if($ID1 != $ID2){
vLogHTML("<B>The value of IA_PD option is un-expected!</B><BR>");
return 1;
}
$count--;
}
return 0;
}
#--------------------------------------------------------------#
# ck_IAPD_prefix_options($frame1, $frame2) #
# #
# Notes: #
# Compare the count of prefix options in IA_PD option #
# Input: #
# 2 references for the frames need to compare #
# match: return 0 #
# not match: return 1 #
#--------------------------------------------------------------#
sub ck_IAPD_prefix_options($$) {
my ($ref_frame1,$ref_frame2) = @_;
my $strBase1 = getMsgTypeLocStr($ref_frame1);
my $strBase2 = getMsgTypeLocStr($ref_frame2);
#check the count of IA_PD prefix options
my $strIndex = "Opt_DHCPv6_IA_PD.Opt_DHCPv6_IA_Prefix#";
#vLogHTML("index is $strBase1.$strIndex");
my $count1 = $$ref_frame1{"$strBase1.$strIndex"};
my $count2 = $$ref_frame2{"$strBase2.$strIndex"};
#vLogHTML("count1 is $count1, and count2 is $count2 <BR>");
if((!defined($count1)) || !defined($count2)){
return 1;
}
if( $count1 eq $count2){
return 0;
}
return 1;
}
#--------------------------------------------------------------#
# getMsgTypeLocStr($ref_frame) #
#--------------------------------------------------------------#
sub getMsgTypeLocStr($){
my $ref_frame = $_[0];
my $base = "";
# get the base location of message type;
foreach(keys %dhcp6_messages) {
$base = $dhcp6_messages{$_};
last if (defined($$ref_frame{$base}));
$base = "";
}
if ("" eq $base) {
vLogHTML("<B>Error message type!</B><BR>");
return 1;
}
else{
return (0,$base);
}
}
#--------------------------------------------------------------#
# send_relay_forward($if, $relaymsg) #
# #
# Notes: #
# make Relayforward Message #
# SUCCESS: return (0, %ret) #
# FAILURE: return (1, ???) #
#--------------------------------------------------------------#
sub send_relay_forward($$) {
my ($if, $relaymsg) = @_;
my $cpp = "";
my $type=$V6evalTool::NutDef{Type};
if($type eq 'router') {
$cpp .= '-D LINK1';
}
# #for send relay-forward request
# my $base = "Frame_Ether.Packet_IPv6.Upp_UDP.Udp_DHCPv6_RelayReply.Udp_DHCPv6_Advertise";
#
# if(defined($SID_OPTION)){
# my ($ret,$cpp_cp) = GetSvrDUIDfromPreMsg($relaymsg,$base);
# $cpp .= $cpp_cp;
# }
createPacketDefinitionFile("DHCPv6_test.def");
vCPP($cpp);
my %ret = vSend3($if, $relaymsg);
parse_relay_message(\%ret);
return (0, %ret) if(0 == $ret{status});
return (1, %ret);
}
#--------------------------------------------------------------#
# send_relay_forward_request($if, $relaymsg, $relayreply, $cpp)#
# #
# Notes: #
# make Relayforward Message #
# SUCCESS: return (0, %ret) #
# FAILURE: return (1, ???) #
#--------------------------------------------------------------#
sub send_relay_forward_request($$$$) {
my ($if, $relaymsg, $relayadvertise, $cpp) = @_;
# my $cpp = "";
$cpp = defined($cpp) ? $cpp : '';
#for send relay-forward request
my $base = "Frame_Ether.Packet_IPv6.Upp_UDP.Udp_DHCPv6_RelayReply.Opt_DHCPv6_RelayMessage.Udp_DHCPv6_Advertise";
if(defined($SID_OPTION)){
my ($ret,$cpp_cp) = GetSvrDUIDfromPreMsg($relayadvertise,$base);
$cpp .= $cpp_cp;
}
createPacketDefinitionFile("DHCPv6_test.def");
vCPP($cpp);
my %ret = vSend3($if, $relaymsg);
parse_relay_message(\%ret);
return (0, %ret) if(0 == $ret{status});
return (1, %ret);
}
#--------------------------------------------------------------#
# CheckTimeOfPrefixOP($refframe1,$refframe2) #
# check time value in Prefix Option #
# #
# IN: #
# $frame1,$frame2: reference of packet frame #
# return: #
# 0: pass #
# 1: fail #
#--------------------------------------------------------------#
sub CheckTimeOfPrefixOP($$){
my($ref_frame1, $ref_frame2) = @_;
#Get the begin index string for message
my $MsgTypeFrame1 = getMsgTypeLocStr($ref_frame1);
my $MsgTypeFrame2 = getMsgTypeLocStr($ref_frame2);
#Compare the value of the Identifier in IA_PD Prefix option
if($$ref_frame1{"$MsgTypeFrame1.Opt_DHCPv6_IA_PD.Identifier"}
== $$ref_frame2{"$MsgTypeFrame2.Opt_DHCPv6_IA_PD.Identifier"}){
if(($$ref_frame1{"$MsgTypeFrame1.Opt_DHCPv6_IA_PD.Opt_DHCPv6_IA_Prefix.ValidLifetime"}
== $$ref_frame2{"$MsgTypeFrame2.Opt_DHCPv6_IA_PD.Opt_DHCPv6_IA_Prefix.ValidLifetime"})
&&
($$ref_frame1{"$MsgTypeFrame1.Opt_DHCPv6_IA_PD.Opt_DHCPv6_IA_Prefix.PreferredLifetime"}
== $$ref_frame2{"$MsgTypeFrame2.Opt_DHCPv6_IA_PD.Opt_DHCPv6_IA_Prefix.PreferredLifetime"}))
{
vLogHTML("The Preferred lifetime & Valid lifetime is same<BR>");
return 0;
}
else{
return 1;
}
}
else{
vLogHTML("<B>NG:Don't found IA_PD option!</B><BR>");
return 1;
}
}
#--------------------------------------------------------------#
# CheckIfExistPrefixOP($frame,$strIndex) #
# check if the special Option indexed by the $strIndex exists in the $frame; #
# #
# IN: #
# $frame: reference of packet frame #
# $str_index:index string for access the special field in the result hash.
# return: #
# 0: pass #
# 1: fail #
#--------------------------------------------------------------#
sub CheckIfExistOPwithIndex($$){
my($ref_frame,$str_index) = @_;
#Get message type index;
my $MsgTypeFrame = getMsgTypeLocStr($ref_frame);
if(!defined($MsgTypeFrame)){
vLogHTML("The message is not valid.<BR>");
}
$MsgTypeFrame .= ".$str_index";
#vLogHTML("Index is $str_index<BR>");
if($$ref_frame{$MsgTypeFrame}){
return 0;
}
return 1;
}
#--------------------------------------------------------------#
# CheckIfExistPrefixOP($frame,$opnum) #
# check if the special Option exists in the $frame; #
# #
# IN: #
# $frame: reference of packet frame #
# return: #
# 0: pass #
# 1: fail #
#--------------------------------------------------------------#
sub CheckIfExistOP($$){
my($frame,$optnum) = @_;
my $FlagAllFound = 0;
my $strCMP= undef;
my $FlagFound = 0;
vLogHTML("<B>Begin check option</B><BR>");
foreach (keys %option_defs) {
if (0 != ($_ & $optnum)) {
my $optionname = $option_defs{$_};
next if (!defined($optionname));
$strCMP = "$optionname#";
$FlagFound = 0;
vLogHTML("Begin check $optionname.<BR>");
foreach my $title (keys %$frame){
if($title =~ /$strCMP/){
vLogHTML("The option $optionname has existed<BR>");
$FlagAllFound |= $_;
$FlagFound = 1;
last;
};
}
#vLogHTML("<FONT COLOR=\"#FF0000\">The option $optionname is not existed.</FONT><BR>") unless $FlagFound ;
}
}
if( $optnum != $FlagAllFound){
return 1;
}
return 0;
}
#--------------------------------------------------------------#
# CheckMessageInRelayOption($frame,$msgname) #
# #
# IN: #
# $frame: reference of packet frame #
# return: #
# 0: pass #
# 1: fail #
#--------------------------------------------------------------#
sub CheckMessageInRelayOption($$){
my ($ref_frame,$msgname) = @_;
my $msg_index = $dhcp6_messages_title{$msgname};
$msg_index .= '#';
my $title = undef;
#vLogHTML("$msg_index<BR>");
foreach my $title (keys %$ref_frame){
#vLogHTML("$title<BR>");
if($title =~/$msg_index/){
return 0;
};
}
return 1;
}
#--------------------------------------------------------------#
# GetFieldValueInMsg($ref_frame,$fieldname) #
# check value in option #
# #
# IN: #
# $ref_frame: reference of packet frame #
# return: #
# $val: pass #
# test exist: fail #
#--------------------------------------------------------------#
sub GetFieldValueInMsg($$){
my($ref_frame,$fieldname) = @_;
my ($ret, $msgindex) = getMsgTypeLocStr($ref_frame);
if(!defined($msgindex)){
vLogHTML("The message is not valid.<BR>");
}
$msgindex .= ".$fieldname";
#vLogHTML("index is $msgindex<BR>");
my $val_field = $$ref_frame{$msgindex};
#if(!defined($val_field)){
# dhcpExitError("Can't found special option.");
#}
return $val_field;
}
#--------------------------------------------------------------#
# check_valueinOption($frame,$opnum,$fieldname,$expVal) #
# check value in option #
# #
# IN: #
# $frame: reference of packet frame #
# return: #
# 0: pass #
# 1: fail #
#--------------------------------------------------------------#
sub check_FieldValueinOption($$$$){
my($frame,$opnum,$fieldname,$expval) = @_;
vLogHTML("Begin check option's value...<BR>");
my ($ret, $msgindex) = getMsgTypeLocStr($frame);
if( 0 != $ret){
dhcpExitFail();
}
my $optype = $option_defs{$opnum};
# now, only support 1 level field following the option name
my $Valfield = $$frame{"$msgindex.$optype.$fieldname"};
#vLogHTML("The index of special field $fieldname is $msgindex.$optype.$fieldname!<BR>");
#vLogHTML($Valfield);
# locate the field index string automatically;
#
if(!defined($Valfield)){
vLogHTML("<B>This field does not exist!</B><BR>");
}
return 0 if ($expval == $Valfield);
vLogHTML("The value of specified field is $Valfield<B></B>,but expected value is <B>$expval</B><BR>");
return 1;
}
#------------------------------------------------------------------#
# check_valueofAnyFieldInOption($frame,$opnum,$fieldname,$expVal) #
# check value of any field in option #
# #
# IN: #
# $frame: reference of packet frame #
# return: #
# 0: pass #
# 1: fail #
#------------------------------------------------------------------#
sub check_valueofAnyFieldInOption($$$$){
my($frame,$opnum,$fieldname,$expval) = @_;
my $strIndex = undef;
my $flgEqual = 0;
my $Valfield = undef; #The actuall value of found field
my $strCMP = $option_defs{$opnum}; #Option name;
foreach my $title (keys %$frame){
if($title =~ /($strCMP)$/){
#Process the first option;
$strIndex = $title.".$fieldname";
if(defined ($$frame{$strIndex})){
$Valfield = $$frame{$strIndex};
if($expval eq $Valfield){
vLogHTML("Begin check $strIndex<BR>");
vLogHTML("value is $Valfield<BR>");
$flgEqual = 1;
last;
}
}
}
#Get the count of the special options
my $optionCount = $$frame{"$title#"};
if($optionCount >1){
#process the other option
for(my $i=2;$i<= $optionCount;$i++){
$strIndex = "$title$i".".$fieldname";
if(defined ($$frame{$strIndex})){
$Valfield = $$frame{$strIndex};
if($expval eq $Valfield){
vLogHTML("Begin check $strIndex<BR>");
vLogHTML("value is $Valfield<BR>");
$flgEqual = 1;
last;
}
}
}
}
}
if(!defined($Valfield)){
dhcpExitError("Can not find specified field!");
return 1;
}
return 0 if (1 == $flgEqual);
dhcpExitError("The value of specified field is $Valfield<B></B>,but expected value is <B>$expval</B><BR>");
return 1;
}
#-----------------------------------------------#
# dhcpCltInit() #
# Initialize dhcpv6 Client #
# #
# IN: #
# #
# return: #
# 0: pass #
# 1: fail #
#-----------------------------------------------#
sub dhcpCltInit(){
vLogHTML("<B>==== NUT Initialization ====</B><BR>");
if ( 0 != vRemote('reboot.rmt','')) {
vLogHTML('<FONT COLOR="#FF0000">Initialization Failed!</FONT>');
return 1;
}
vLogHTML("<B>==== NUT Initialization OK ====</B><BR>");
vSleep(10);
return 0;
}
#-----------------------------------------------#
# dhcpCltRestart() #
# Restart dhcpv6 Client program #
# #
# IN: #
# #
# return: #
# 0: pass #
# 1: fail #
#-----------------------------------------------#
sub dhcpCltRestart(){
my $ret = 1;
my $IF0_NUT = $V6evalTool::NutDef{Link0_device};
$ret = vRemote("dhcp6c.rmt", "restart", "link0=$IF0_NUT");
if($ret != 0) {
vLogHTML('<FONT COLOR="#FF0000">Cannot Restart DHCPv6 Client.</FONT><BR>');
dhcpExitFail;
};
}
#-----------------------------------------------#
# dhcpCltStart() #
# Start dhcpv6 Client program #
# #
# IN: #
# #
# return: #
# 0: pass #
# 1: fail #
#-----------------------------------------------#
sub dhcpCltStart(){
my $ret = 1;
my $IF0_NUT = $V6evalTool::NutDef{Link0_device};
$ret = vRemote("dhcp6c.rmt", "start", "link0=$IF0_NUT");
if($ret != 0){
vLogHTML('<FONT COLOR="#FF0000">Cannot Initialize DHCPv6 Client program!</FONT><BR>');
dhcpExitFail;
};
}
#-----------------------------------------------#
# check_equal($$;$) #
# check if the former is equalt to latter #
# even if there is random factor #
# #
# IN: #
# former: value to be checked #
# latter: rand*latter is the latter #
# return: #
# 0: pass #
# 1: fail #
#-----------------------------------------------#
sub check_equal($$;$){
my ($former,$latter,$RAND) = @_;
if (defined $RAND){
if(($former < ($latter - $latter*$RAND)) or ($former > ($latter + $latter*$RAND))){
return 1;
}
else{
return 0;
}
}
else{
if($former != $latter){
return 1;
}
else{
return 0;
}
}
}
#-----------------------------------------------#
# sub ckRelayForwardPeerAddress($$);
# Check whether the peer-address is equal to the previous message's source address #
# * Only can be used for the relay option in the first level of Relay-forward message #
# IN: #
# \%relayframe: reference to relay message #
# \%ref_sourceframe: reference to source message #
# return: #
# 0: pass #
# 1: fail #
#-----------------------------------------------#
sub ckRelayForwardPeerAddress ($$){
my ($ref_relayframe,$ref_sourceframe) = @_;
my ($val_peeraddress,$val_sourceaddress)= undef;
$val_sourceaddress = $$ref_sourceframe{"Frame_Ether.Packet_IPv6.Hdr_IPv6.SourceAddress"};
$val_peeraddress = $$ref_relayframe{"Frame_Ether.Packet_IPv6.Upp_UDP.Udp_DHCPv6_RelayForward.PeerAddr"};
if($val_sourceaddress ne $val_peeraddress){
vLogHTML("<FONT COLOR=\"#FF0000\">The peer-address ($val_peeraddress) in the Relay message is not equal to the previous message's source address ($val_sourceaddress)!</FONT><BR>");
return 1;
}
vLogHTML("<B>Checking the peer-address field is passed.</B><BR>");
return 0;
}
#-----------------------------------------------#
# sub ckRelayForwardLinkAddress($$);
# Check the link-address field in the Relay-forward message from other Relay agent #
# Only can be used for the relay option in the first level of Relay message #
# IN: #
# \%frame1: reference to relay message #
# $globaladd: global address
# return: #
# 0: pass #
# 1: fail #
#-----------------------------------------------#
sub ckRelayForwardLinkAddress ($$){
my ($ref_relayframe,$globaladd) = @_;
# check the hop-count
my $val =$$ref_relayframe{"Frame_Ether.Packet_IPv6.Upp_UDP.Udp_DHCPv6_RelayForward.LinkAddr"};
if(0 eq $val){
vLogHTML("The link-address is 0<BR>");
return 0;
}
elsif ($globaladd eq $val){
vLogHTML("The link-address is global address<BR>");
return 0;
}
elsif(0 == CheckIfExistOP($ref_relayframe,$CMP_IID)){
vLogHTML("<B>Using Interface-ID option</B><BR>");
return 0;
}
vLogHTML("<FONT COLOR=\"#FF0000\">The Link-address($val) in the Relay message is invalid!</FONT><BR>");
return 1;
}
#-----------------------------------------------#
# sub ckRelayMsgHopLimit($);
# Check the value of HopLimit field in the Relay message #
# Only can be used for the relay option in the first level of Relay message #
# IN: #
# \%relayframe: reference to relay message #
# $expectVal
# return: #
# 0: pass #
# 1: fail #
#-----------------------------------------------#
sub ckRelayMsgHopLimit ($$){
my ($ref_relayframe,$expectval) = @_;
my $val = undef;
# check the HopLimit
$val = $$ref_relayframe{"Frame_Ether.Packet_IPv6.Hdr_IPv6.HopLimit"};
if("$expectval" ne $val){
vLogHTML("<FONT COLOR=\"#FF0000\">The HopLimit value in the Relay message is $val, but the value expected is 32!</FONT><BR>");
return 1;
}
vLogHTML("<B>Checking the HopLimit field is passed.</B><BR>");
return 0;
}
#-----------------------------------------------#
# sub ckRelayForwardMsgHopCount($$);
# Check the value of hop-count field in the Relay message #
# Only can be used for the relay option in the first level of Relay message #
# IN: #
# \%frame1: reference to relay message #
# $expectVal
# return: #
# 0: pass #
# 1: fail #
#-----------------------------------------------#
sub ckRelayForwardMsgHopCount ($$){
my ($ref_relayframe ,$expectval) = @_;
my $val = undef;
# check the hop-count
$val = $$ref_relayframe{"Frame_Ether.Packet_IPv6.Upp_UDP.Udp_DHCPv6_RelayForward.HopCount"};
if("$expectval" ne $val){
vLogHTML("The hop-count value in the Relay message is $val, but the value expected is 0!<BR>");
return 1;
}
vLogHTML("<B>Checking the hop-count field is passed.</B><BR>");
return 0;
}
#-----------------------------------------------#
# comapre_message($$) #
# Compare two frame #
# #
# IN: #
# \%frame1: reference to frame 1 #
# \%frame2: reference to frame 2 #
# return: #
# 0: pass #
# 1: fail #
#-----------------------------------------------#
sub compare_message($$){
my ($frame1,$frame2) = @_;
my ($base1,$base2) = (undef,undef);
my ($transid1,$transid2) = (undef,undef);
my ($baseopts1,$baseopts2) = (undef,undef);
foreach(keys %dhcp6_messages){
$base1 = $dhcp6_messages{$_};
last if (defined($$frame1{$base1}));
$base1 = "";
}
foreach(keys %dhcp6_messages){
$base2 = $dhcp6_messages{$_};
last if (defined($$frame2{$base2}));
$base2 = "";
}
#compare the msg-type
if($base1 ne $base2){
vLogHTML("<FONT COLOR=\"#FF0000\">first message: $base1 </FONT><BR>");
vLogHTML("<FONT COLOR=\"#FF0000\">second message: $base2 </FONT><BR>");
vLogHTML('<FONT COLOR="#FF0000"> message type is not same </FONT><BR>');
return 1;
}
#compare the identifier
$transid1 = "$base1"."."."Identifier";
$transid2 = "$base2"."."."Identifier";
if($$frame1{$transid1} ne $$frame2{$transid2}){
vLogHTML('<FONT COLOR="#FF0000"> message identifier is not same </FONT><BR>');
return 1;
}
#compare the options
foreach(keys %option_defs) {
$baseopts1 = "$base1"."."."$option_defs{$_}";
$baseopts2 = "$base2"."."."$option_defs{$_}";
if($$frame1{$baseopts1} ne $$frame2{$baseopts2}){
print "\n $$frame1{$baseopts1}";
print "\n $$frame2{$baseopts2}";
vLogHTML('<FONT COLOR="#FF0000"> message option is not same </FONT><BR>');
return 1;
}
}
return 0;
}
sub DebugStrOut($){
#my $str = $_[0];
my ($str) = @_;
if($DHCP_CHECK_DEBUG){
vLogHTML("$str <BR>");
}
}
sub compare_iaid($$$){
my ($frame1, $frame2, $optype)= @_;
my ($iaid1, $iaid2) = (0, 0);
my ($base1, $base2) = (undef, undef);
my ($optbase1, $optbase2) = (undef, undef);
foreach(keys %dhcp6_messages){
$base1 = $dhcp6_messages{$_};
last if (defined($$frame1{$base1}));
$base1 = "";
}
foreach(keys %dhcp6_messages){
$base2 = $dhcp6_messages{$_};
last if (defined($$frame2{$base2}));
$base2 = "";
}
$optbase1 = $base1.".".$option_defs{"$optype"};
$optbase2 = $base2.".".$option_defs{"$optype"};
$iaid1 = $$frame1{$optbase1."."."Identifier"};
$iaid2 = $$frame2{$optbase2."."."Identifier"};
print "iaid1 = $iaid1 \n";
print "iaid2 = $iaid2 \n";
if($iaid1 eq $iaid2){
return 0;
}
else{
vLogHTML("<FONT COLOR=\"#FF0000\">First message IAID is $iaid1 <FONT><BR>");
vLogHTML("<FONT COLOR=\"#FF0000\">Second message IAID is $iaid2 <FONT><BR>");
return 1;
}
}
#-----------------------------------------------#
# compare_id($$$) #
# compare the SID or CID #
# #
# IN: #
# $frame1 #
# $frame2 #
# $optype #
# return: #
# 0: pass #
# 1: fail #
#-----------------------------------------------#
sub compare_id($$$){
my ($frame1, $frame2, $optype)= @_;
my ($base1, $base2) = (undef, undef);
my ($optbase1, $optbase2) = (undef, undef);
my ($duid1, $duid2) = (undef, undef);
my $retval = 1;
foreach(keys %dhcp6_messages){
$base1 = $dhcp6_messages{$_};
last if (defined($$frame1{$base1}));
$base1 = "";
}
foreach(keys %dhcp6_messages){
$base2 = $dhcp6_messages{$_};
last if (defined($$frame2{$base2}));
$base2 = "";
}
$optbase1 = $base1.".".$option_defs{"$optype"};
$optbase2 = $base2.".".$option_defs{"$optype"};
foreach(keys %duid_types){
my $duidbase1 = $optbase1.".".$duid_types{$_};
my $duidbase2 = $optbase2.".".$duid_types{$_};
my $duidtype1 = $$frame1{$duidbase1."."."Type"};
my $duidtype2 = $$frame2{$duidbase2."."."Type"};
if(defined($duidtype1) and defined($duidtype2)){
#vLogHTML("optbase1 : $optbase1 <BR>");
#vLogHTML("optbase2 : $optbase2 <BR>");
#vLogHTML("duidbase1 : $duidbase1 <BR>");
#vLogHTML("duidbase2 : $duidbase2 <BR>");
#vLogHTML("duidtype1 : $duidtype1 <Br>");
#vLogHTML("duidtype2 : $duidtype2 <BR>");
if($duid_types{$_} eq "DHCPv6_DUID_LLT_Ether"){
$retval = check_duid_para($frame1,$frame2,$duidbase1,$duidbase2,"LinkLayerAddress");
$retval |= check_duid_para($frame1,$frame2,$duidbase1,$duidbase2,"Time");
if($retval !=0){
vLogHTML("<FONT COLOR=\"#FF0000\">Not Match! <FONT><BR>");
return 1;
}
last;
}
elsif($duid_types{$_} eq "DHCPv6_DUID_EN"){
$retval = check_duid_para($frame1,$frame2,$duidbase1,$duidbase2,"EnterpriseNumber");
$retval |= check_duid_para($frame1,$frame2,$duidbase1,$duidbase2,"Identifier");
if($retval !=0){
vLogHTML("<FONT COLOR=\"#FF0000\">Not Match! <FONT><BR>");
return 1;
}
last;
}
elsif($duid_types{$_} eq "DHCPv6_DUID_LL_Ether"){
$retval = check_duid_para($frame1,$frame2,$duidbase1,$duidbase2,"LinkLayerAddress");
if($retval !=0){
vLogHTML("<FONT COLOR=\"#FF0000\">Not Match! <FONT><BR>");
return 1;
}
last;
}
elsif($duid_types{$_} eq "DHCPv6_DUID_LLT_ANY"){
$retval = check_duid_para($frame1,$frame2,$duidbase1,$duidbase2,"LinkLayerAddress");
$retval |= check_duid_para($frame1,$frame2,$duidbase1,$duidbase2,"Time");
$retval |= check_duid_para($frame1,$frame2,$duidbase1,$duidbase2,"HardwareType");
if($retval !=0){
vLogHTML("<FONT COLOR=\"#FF0000\">Not Match! <FONT><BR>");
return 1;
}
last;
}
}
}
return 0;
}
sub check_duid_para($$$$$){
my ($frame1, $frame2, $duidbase1, $duidbase2, $parameter) = @_;
my ($value1, $value2) = (undef, undef);
$value1 = $$frame1{$duidbase1.".".$parameter};
$value2 = $$frame2{$duidbase2.".".$parameter};
#vLogHTML("value1 = $value1 <BR> ");
#vLogHTML("value2 = $value2 <BR> ");
if(!defined($value1)){
vLogHTML("<FONT COLOR=\"#FF0000\">invalid parameter ! <FONT><BR>");
return 1;
}
if(!defined($value2)){
vLogHTML("<FONT COLOR=\"#FF0000\">invalid parameter ! <FONT><BR>");
return 1;
}
if($value1 eq $value2){
#vLogHTML("same content <BR>");
return 0;
}
return 1;
}
#-----------------------------------------------#
# check_dest_ipaddress($) #
# check whether dest IP address is unicast #
# IP address #
# #
# IN: #
# $frame #
# #
# return: #
# 0: Multicast #
# 1: Unicast #
#-----------------------------------------------#
sub check_dest_ipaddress($){
my ($frame) = @_;
my $destIPaddr = $$frame{"Frame_Ether\.Packet_IPv6\.Hdr_IPv6\.DestinationAddress"};
print "\n dest IP Address is $destIPaddr \n";
if($destIPaddr =~ /ff02::1:2/){
vLogHTML('<FONT COLOR="#FF0000"> Destination IP address is Multicast Address(ff02::1:2).</FONT><BR>');
return 0;
}
return 1;
}
#-----------------------------------------------#
# check_ipaddr_local($$) #
# check whether dest IP address is link-local #
# IP address #
# #
# IN: #
# $frame #
# $type #
# return: #
# 0: non-link-local IP Address #
# 1: Fail or link-local IP Address #
#-----------------------------------------------#
sub check_ipaddr_local($$){
my ($frame,$type) = @_;
my $ipaddress = undef;
# vLogHTML("<FONT COLOR=\"#FF0000\"><B> Type is $type </B></FONT><BR>");
if($type eq "SourceAddress"){
$ipaddress = $$frame{"Frame_Ether\.Packet_IPv6\.Hdr_IPv6\.SourceAddress"};
}
elsif($type eq "DestinationAddress"){
$ipaddress = $$frame{"Frame_Ether\.Packet_IPv6\.Hdr_IPv6\.DestinationAddress"};
}
else{
vLogHTML("<FONT COLOR=\"#FF0000\"><B> Address Type is error!</B></FONT><BR>");
return 1;
}
vLogHTML("<FONT><B> Address is $ipaddress </B></FONT><BR>");
if ($ipaddress !~ /fe80::/){
vLogHTML("<FONT COLOR=\"#FF0000\"><B>$type is not Link-local Address! </B></FONT><BR>");
return 1;
}
return 0;
}
#-----------------------------------------------#
# get_nut_link_number($) #
# According to Source MAC Address, get Link #
# number of NUT #
# #
# IN: #
# $frame #
# #
# return: #
# 0~4: Normally return value #
# 5: Abnormally return value #
#-----------------------------------------------#
sub get_nut_link_number($){
my ($frame) = @_;
my $macaddress = undef;
$macaddress = $$frame{"Frame_Ether.Hdr_Ether.SourceAddress"};
vLogHTML("<FONT COLOR=\"#FF0000\"><B>NUT Link MAC Address is $macaddress </B></FONT><BR>");
for(my $n=0; $n<=4; $n++){
if(defined($V6evalTool::NutDef{"Link".$n."_addr"})){
if ($V6evalTool::NutDef{"Link".$n."_addr"} eq $macaddress )
{
return $n;
}
}
}
return 5;
}
#-----------------------------------------------#
# get_udp_destport($) #
# From message, get destination UDP port #
# number #
# #
# IN: #
# $frame #
# #
# return: #
# 0: wrong number #
# others: return port value #
#-----------------------------------------------#
sub get_udp_destport($){
my ($frame) = @_;
my $port = undef;
$port = $$frame{"Frame_Ether\.Packet_IPv6\.Upp_UDP\.Hdr_UDP\.DestinationPort"};
return $port;
}
#-----------------------------------------------#
# parse_IAPD_option($) #
# From message, parse the content of IAPD #
# #
# #
# IN: #
# $frame #
# #
# return: #
# #
# #
#-----------------------------------------------#
sub parse_IAPD_option($){
my ($frame) = @_;
my $base = undef;
foreach(keys %dhcp6_messages) {
$base = $dhcp6_messages{$_};
last if (defined($$frame{$base}));
$base = "";
}
my $baseopt = $base."."."Opt_DHCPv6_IA_PD";
#if(!defined($$frame{$baseopt})){
# vLogHTML("<FONT COLOR=\"#FF0000\">IA_PD option not found! </FONT><BR>");
# return 0;
#}
vLogHTML("<B>IA_PD option 1:</B><BR>");
vLogHTML("<B>Identifier = $$frame{$baseopt.\".\".\"Identifier\"}</B><BR>");
vLogHTML("<B>Time1 = $$frame{$baseopt.\".\".\"Time1\"}</B><BR>");
vLogHTML("<B>Time2 = $$frame{$baseopt.\".\".\"Time2\"}</B><BR>");
my $num = 2;
while(defined($$frame{$baseopt.$num})){
vLogHTML("<B>IA_PD option $num:</B><BR>");
vLogHTML("<B>Identifier = $$frame{$baseopt.$num.\".\".\"Identifier\"}</B><BR>");
vLogHTML("<B>Time1 = $$frame{$baseopt.$num.\".\".\"Time1\"}</B><BR>");
vLogHTML("<B>Time2 = $$frame{$baseopt.$num.\".\".\"Time2\"}</B><BR>");
$num ++;
}
}
#-----------------------------------------------#
# parse_IAPrefix_option($) #
# From message, parse the content of IAPD #
# Prefix option #
# #
# IN: #
# $frame #
# #
# return: #
# 0: PASS #
# 1: FAIL #
#-----------------------------------------------#
sub parse_IAPrefix_option($){
my ($frame) = @_;
my $base = undef;
foreach(keys %dhcp6_messages) {
$base = $dhcp6_messages{$_};
last if (defined($$frame{$base}));
$base = "";
}
my $baseopt = $base."."."Opt_DHCPv6_IA_PD"."."."Opt_DHCPv6_IA_Prefix" ;
if(!defined($$frame{$baseopt})){
vLogHTML("<FONT COLOR=\"#FF0000\">IA_Prefix option not found! </FONT><BR>");
return 1;
}
vLogHTML("<B>PrefferedLifetime = $$frame{$baseopt.\".\".\"PreferredLifetime\"}</B><BR>");
vLogHTML("<B>ValidLifetime = $$frame{$baseopt.\".\".\"ValidLifetime\"}</B><BR>");
vLogHTML("<B>PrefixLength = $$frame{$baseopt.\".\".\"PrefixLength\"}</B><BR>");
vLogHTML("<B>Prefix = $$frame{$baseopt.\".\".\"Prefix\"}</B><BR>");
return 0;
}
sub get_OptRequstCode($){
my ($frame) = @_;
my $base = undef;
foreach(keys %dhcp6_messages) {
$base = $dhcp6_messages{$_};
last if (defined($$frame{$base}));
$base = "";
}
my $baseopt = $base."."."Opt_DHCPv6_OptionRequest";
if(!defined($$frame{$baseopt})){
vLogHTML("<FONT COLOR=\"#FF0000\">Option Request option not found! </FONT><BR>");
return 1;
}
foreach(keys %$frame){
print "$_ : $$frame{$_}\n";
}
my $OptionRequestCode = $$frame{$baseopt."."."OptionCode"};
print "\nReuested-Option-Code is $OptionRequestCode \n";
return $OptionRequestCode;
}
sub lookup_OptRequestCode($$){
my ($frame, $testcode) = @_;
my $base = undef;
foreach(keys %dhcp6_messages) {
$base = $dhcp6_messages{$_};
last if (defined($$frame{$base}));
$base = "";
}
my $baseopt = $base."."."Opt_DHCPv6_OptionRequest";
if(!defined($$frame{$baseopt})){
vLogHTML("<FONT COLOR=\"#FF0000\">Option Request option not found! </FONT><BR>");
return 1;
}
my $optlen = $$frame{$baseopt."."."Length"};
my $optnum = $optlen/2;
my $count = 0;
my $reqoptcode = 0;
my $found = 1;
$reqoptcode = $$frame{$baseopt."."."OptionCode"};
print "OptionRequestCode = $reqoptcode\n";
if ($reqoptcode eq $testcode){
$found = 0;
}
if($optnum eq 1){
return $found;
}
else{
for($count = 2; $count <= $optnum; $count++){
$reqoptcode = $$frame{$baseopt."."."OptionCode"."_".$count};
print "OptionRequestCode = $reqoptcode\n";
if ($reqoptcode eq $testcode){
$found = 0;
}
}
return $found;
}
}
#-----------------------------------------------#
# check_Auth_MD5($) #
# From message, calculate Authenticator MD5 #
# #
# IN: #
# $frame $secret_key #
# #
# return: #
# 0: PASS #
# 1: FAIL #
#-----------------------------------------------#
sub check_Auth_MD5($$){
my ($ret_ref,$secretkey) = @_;
my $udp_path = 'Frame_Ether.Packet_IPv6.Upp_UDP';
$ret_ref->{$udp_path} =~ /(Udp_DHCPv6_\S+)/;
my $udp_name = $1;
unless(defined($udp_name)){
DebugStrOut("check_Auth_MD5:can't find DHCPv6 section\n");
return 1;
}
my $dhcp_path = "$udp_path.$udp_name";
my $type = $ret_ref->{"${dhcp_path}.Type"};
my $indetifier = $ret_ref->{"${dhcp_path}.Identifier"};
my $packet_string = sprintf("%02x%06x",$type,$indetifier);
my $receive_md5 = '';
my @dhcp_names = split(' ',$ret_ref->{$dhcp_path});
foreach my $dhcp_name (@dhcp_names){
if($dhcp_name =~ /^Opt_/){
my $ret = get_Opt_String("$dhcp_path.$dhcp_name",
$ret_ref,
\$packet_string,
\$receive_md5);
if($ret != 0){
return(1);
}
}
}
my $packet_bin = pack("H*", $packet_string);
my $key_bin = pack("H*", Ascii2Hex($secretkey));
my $calc_md5=hmac_md5_hex($packet_bin, $key_bin);
DebugStrOut("############packet##############");
DebugStrOut("$packet_string");
DebugStrOut("############calc_md5############");
DebugStrOut("$calc_md5");
DebugStrOut("############rcv_md5#############");
DebugStrOut("$receive_md5");
DebugStrOut("################################");
if($calc_md5 eq $receive_md5){
vLogHTML("Authentication HMAC HASH matched.<BR>");
}else{
DebugStrOut("Authentication HMAC HASH does not match!");
return 1;
}
return 0;
}
sub get_Opt_String($$$$){
my ($dhcp_path,$ret_ref,$string_ref,$md5_ref) = @_;
my $code = $ret_ref->{"${dhcp_path}.Code"};
my $length = $ret_ref->{"${dhcp_path}.Length"};
$$string_ref .= sprintf("%04x%04x",$code,$length);
if($option_codes{$code} =~ /OPTION_CLIENTID/ ||
$option_codes{$code} =~ /OPTION_SERVERID/
){
$ret_ref->{$dhcp_path} =~ /(DHCPv6_DUID\S+)/;
my $duid_name = $1;
my $duid_path = "${dhcp_path}.$duid_name";
my $ret = get_DUID_Strig($duid_path,$ret_ref,$length,$string_ref);
if($ret != 0){
return(1);
}
}elsif($option_codes{$code} =~ /OPTION_IA_NA/ ||
$option_codes{$code} =~ /OPTION_IA_TA/
){
my $iaid = $ret_ref->{"${dhcp_path}.Identifier"};
my $time1 = $ret_ref->{"${dhcp_path}.Time1"};
my $time2 = $ret_ref->{"${dhcp_path}.Time2"};
$$string_ref .= sprintf("%08x%08x%08x",$iaid,$time1,$time2);
}elsif($option_codes{$code} =~ /OPTION_IAADDR/){
my $address = addressToBytes($ret_ref->{"${dhcp_path}.Address"});
my $preferredlifetime = $ret_ref->{"${dhcp_path}.PreferredLifetime"};
my $validlifetime = $ret_ref->{"${dhcp_path}.ValidLifetime"};
$$string_ref .= $address;
$$string_ref .= sprintf("%08x%08x",$preferredlifetime,$validlifetime);
}elsif($option_codes{$code} =~ /OPTION_ORO/){
my $opt_num = $length / 2;
for(my $i=0;$i < $opt_num;$i++){
my $optioncode = '';
if($i > 0){
$optioncode = $ret_ref->{"${dhcp_path}.OptionCode${i}"};
}else{
$optioncode = $ret_ref->{"${dhcp_path}.OptionCode"};
}
$$string_ref .= sprintf("%04x",$optioncode);
}
}elsif($option_codes{$code} =~ /OPTION_ELAPSED_TIME/){
my $time = $ret_ref->{"${dhcp_path}.Time"};
$$string_ref .= sprintf("%04x",$time);
}elsif($option_codes{$code} =~ /OPTION_AUTH/){
my $protocol = $ret_ref->{"${dhcp_path}.Protocol"};
my $algorithm = $ret_ref->{"${dhcp_path}.Algorithm"};
my $rdm = $ret_ref->{"${dhcp_path}.RDM"};
my $replaydetection = $ret_ref->{"${dhcp_path}.ReplayDetection"};
$$string_ref .= sprintf("%02x%02x%02x",$protocol,$algorithm,$rdm);
$$string_ref .= $replaydetection;
#only DHCPv6_Auth_Delayed is used for while
if($protocol == 2){
my $auth_path = "${dhcp_path}.DHCPv6_Auth_Delayed";
my $realm = $ret_ref->{"${auth_path}.Realm"};
my $identifier = $ret_ref->{"${auth_path}.Identifier"};
my $authenticator = $ret_ref->{"${auth_path}.Authenticator"};
my $auth_length = length($authenticator);
$$md5_ref = $authenticator;
$$string_ref .= $realm;
$$string_ref .= sprintf("%08x",$identifier);
$$string_ref .= sprintf("%s","0"x$auth_length);
}elsif($protocol == 3){
my $auth_path = "${dhcp_path}.DHCPv6_Auth_ReconfigureKey";
my $type = $ret_ref->{"${auth_path}.Type"};
my $data = $ret_ref->{"${auth_path}.data"};
$$md5_ref = $data;
$$string_ref .= sprintf("%02x",$type);
$$string_ref .= sprintf("%s","0"x32);
}
}elsif($option_codes{$code} =~ /OPTION_STATUS_CODE/){
my $statuscode = $ret_ref->{"${dhcp_path}.StatusCode"};
my $message = $ret_ref->{"${dhcp_path}.Message"};
$$string_ref .= sprintf("%04x",$statuscode);
$$string_ref .= $message;
}elsif($option_codes{$code} =~ /OPTION_RECONF_MSG/){
my $msgtype = $ret_ref->{"${dhcp_path}.Type"};
$$string_ref .= sprintf("%02x",$msgtype);
}else{
DebugStrOut("get_Opt_String:unexpected option_code:$code");
return(1);
}
foreach my $dhcp_name (split(" ",$ret_ref->{$dhcp_path})){
if($dhcp_name =~ /^Opt_/){
my $ret = get_Opt_String($dhcp_path . "." . $dhcp_name,$ret_ref,$string_ref,$md5_ref);
if($ret != 0){
return(1);
}
}
}
return 0;
}
sub get_DUID_Strig($$$$){
my ($duid_path,$ret_ref,$length,$string_ref) = @_;
my $type = $ret_ref->{"$duid_path.Type"};
if($duid_types{$type} eq "DHCPv6_DUID_LLT_Ether"){
my $hardwaretype = $ret_ref->{"${duid_path}.HardwareType"};
my $time = $ret_ref->{"${duid_path}.Time"};
my $linklayeraddress = $ret_ref->{"${duid_path}.LinkLayerAddress"};
$$string_ref .= sprintf("%04x%04x%08x",$type,$hardwaretype,$time);
$linklayeraddress =~ s/://g;
$$string_ref .= $linklayeraddress;
}elsif($duid_types{$type} eq "DHCPv6_DUID_LL_Ether"){
my $hardwaretype = $ret_ref->{"${duid_path}.HardwareType"};
my $linklayeraddress = $ret_ref->{"${duid_path}.LinkLayerAddress"};
$$string_ref .= sprintf("%04x%04x",$type,$hardwaretype);
$linklayeraddress =~ s/://;
$$string_ref .= $linklayeraddress;
}elsif($duid_types{$type} eq "DHCPv6_DUID_EN"){
my $enterprisenumber = $ret_ref->{"${duid_path}.EnterpriseNumber"};
my $id = $ret_ref->{"${duid_path}.Identifier"};
my $endofid = $ret_ref->{"${duid_path}.[Needless].data"};
my $duid_length = $length - 6;
$$string_ref .= sprintf("%04x%08x%0${duid_length}x",$type,$enterprisenumber,$id);
}else{
DebugStrOut("get_DUID_Strig:unexpected DUID type:$type");
return 1;
}
return 0;
}
##############################################
# Change expression from Ascii to Byte string
#
# return value: byte expression string
##############################################
sub addressToBytes($){
my ($addString) = @_;
my $rtnString = undef;
my @addressCells = split(':',$addString);
my $cellNum = @addressCells;
if($cellNum < 8){
my $colons = ':' x (8 - $cellNum + 2);
$addString =~ s/::/$colons/;
}
@addressCells = split(/:/,$addString,-1);
my $num = 0;
for(;$num < 8;$num++){
$rtnString .= sprintf("%04s",$addressCells[$num]);
}
DebugStrOut("Original Address: $addString -> Address Bytes: $rtnString");
return $rtnString;
}
########################################################################
__END__
=head1 NAME
DHCPv6_common - Perl module for DHCPv6
=head1 SYNOPSIS
use DHCPv6_common;
=head1 ENVIRONMENT
=head1 DESCRIPTION
=head1 FILES
=head1 SUPPORTED FUNCTIONS
=over 4
=head1 dhcpReset
sub dhcpReset()
after test, reset the test environment.
=head1 dhcpExitError
sub dhcpExitError($)
Exit with error message.
=cut