#!/pkg/bin/ksh
# ---------------------------------------------------------------------
# macsec_show_techsupport - Show tech-support script for macsec
#
# Dec 2015, Srivathsan S
#
# Copyright (c) 2014-2019, 2021-2023 by cisco Systems, Inc.
# All rights reserved.
#--------------------------------------------------------------------

# This script fragment contains the code for the following functions
# - print_main_heading
# - print_command_heading
# - run_single_command
# - run_commands
# - run_single_command_on_all_nodes
# - run_commands_on_all_nodes
# - default_parser_function
. /pkg/bin/show_tech_main_fragment

# List each set of show commands to be run. Each set must finish with an empty
# string. Note that it is important to use single quotes rather than double
# quotes for the strings containing your commands.

__cardtype="unspecified"

# Set the default values of the file name for which show tech-support macsec 
# is to run and the file it is to write to.
# Read in the arguments to the script, setting node_required and filename
# according to these arguments.
# Note that it is important for security reasons that users can only enter
# alphanumeric filenames and nodes and that anywhere calling this script must
# enforce this.
while [ "$#" -gt "0" ]; do
    case "$1" in
        -t) __cardtype="$2"; shift 2;;
        *)  default_parser_function "$@"; shift $#;;
    esac
done

if [ "$__cardtype" == "unspecified" ]; then
    __cardtype=`node_type`
fi

 # global commands on RP


###############################################################################
# Show commands that run once per LR                                          #
###############################################################################


sys_exec[1]='show install active'
if [[ "$platform" != "viking" ]]; then
sys__ksh[1]='sdr_instcmd show install active'
else
sys__ksh[1]='instcmd show install active'
fi

if [[ "$platform" != "viking" ]]; then
sys_exec[2]='show install repository'
sys__ksh[2]='sdr_instcmd show install repository'
else
sys_exec[2]='show install inactive'
sys__ksh[2]='instcmd show install inactive'
fi

sys_exec[3]='show version'
if [[ "$platform" != "viking" ]]; then
sys__ksh[3]='ng_show_version'
else
sys__ksh[3]='show_version'
fi

sys_exec[4]='show platform'
if [[ "$platform" != "viking" ]]; then
sys__ksh[4]='show_platform_sysdb'
else
sys__ksh[4]='show_platform_vkg'
fi

sys_exec[5]=''
sys__ksh[5]=''


###############################################################################
# Show commands that run on every RP                                          #
###############################################################################


rp_exec[1]='show logging'
rp__ksh[1]='show_logging'

rp_exec[2]='show redundancy location all'
rp__ksh[2]='redcon_show -n all'

rp_exec[3]='show context location all'
if [[ "$platform" == "panini" ]]; then 
    rp__ksh[3]='corehelper_context -c 0x1 -n all'
else
    rp__ksh[3]='dumper_context -c 0x1 -n all'
fi

rp_exec[4]='show running-config'
rp__ksh[4]='nvgen -c -l 1 -t 1 -o 1'

rp_exec[5]='show ip int brief'
rp__ksh[5]='show_ip_interface -b -v all'

rp_exec[6]='show process macsec_ea location all'
rp__ksh[6]='sysmgr_show -o -p macsec_ea -n all'

rp_exec[7]='show process macsec_mka location all'
rp__ksh[7]='sysmgr_show -o -p macsec_mka -n all'

rp_exec[8]='show macsec policy'
rp__ksh[8]='show_macsec_mka -m -p all'

rp_exec[9]='show macsec mka session'
rp__ksh[9]='show_macsec_mka -m -s all'

rp_exec[10]='show macsec mka summary'
rp__ksh[10]='show_macsec_mka -m -u'

rp_exec[11]='show macsec mka session detail'
rp__ksh[11]='show_macsec_mka -m -s detail'

rp_exec[12]='show macsec mka interface'
rp__ksh[12]='show_macsec_mka -m -i all'

rp_exec[13]='show macsec mka interface detail'
rp__ksh[13]='show_macsec_mka -m -i all-detail'

rp_exec[14]='show macsec mka standby session'
rp__ksh[14]='show_macsec_mka -m -s all -h'

rp_exec[15]='show macsec mka standby summary'
rp__ksh[15]='show_macsec_mka -m -u -h'

rp_exec[16]='show macsec mka standby session detail'
rp__ksh[16]='show_macsec_mka -m -s detail -h'

rp_exec[17]='show macsec mka standby interface'
rp__ksh[17]='show_macsec_mka -m -i all -h'

rp_exec[18]='show macsec mka standby interface detail'
rp__ksh[18]='show_macsec_mka -m -i all-detail -h'

rp_exec[19]='show macsec mka trace all location $location'
rp__ksh[19]='show_macsec_mka_ltrace -i $fq_nodeid -A'

rp_exec[20]='show macsec ea trace all location $location'
rp__ksh[20]='show_macsec_ea_ltrace -i $fq_nodeid -A'

rp_exec[21]='show macsec mka client trace all location $location'
rp__ksh[21]='show_macsec_mka_client_ltrace -i $fq_nodeid -A'

rp_exec[22]='show macsec open-config trace'
rp__ksh[22]='oc_macsec_show_ltrace'

rp_exec[23]='show key chain trace client macsec both location $location'
rp__ksh[23]='show_ltrace_kc -i $fq_nodeid -C macsec_mka -W -U'

rp_exec[24]=''
rp__ksh[24]=''


###############################################################################
# Show commands of macsec stats that run on every LC                       #
###############################################################################
lc_exec[1]='show macsec mka statistics location $location'
lc__ksh[1]='show_macsec_mka -m -t loc -l $fq_nodeid'

lc_exec[2]='show macsec mka trace all location $location'
lc__ksh[2]='show_macsec_mka_ltrace -i $fq_nodeid -A'

lc_exec[3]='show macsec ea idb location $location'
lc__ksh[3]='show_macsec_ea -i -l $fq_nodeid'

lc_exec[4]='show macsec ea trace all location $location'
lc__ksh[4]='show_macsec_ea_ltrace -i $fq_nodeid -A'


lc_exec[5]='show macsec mka client trace all location $location'
lc__ksh[5]='show_macsec_mka_client_ltrace -i $fq_nodeid -A'

lc_exec[6]='show key chain trace client macsec both location $location'
lc__ksh[6]='show_ltrace_kc -i $fq_nodeid -C macsec_mka -W -U'

lc_exec[7]=''
lc__ksh[7]=''

###############################################################################
# Show commands for collecting mka and secy interface stats                 #
###############################################################################
i=1

# find fq_nodeid for the node
# QNX does not provide node_list_generation but 'uname -n' provides the node name
# Linux supports node_list_generation and node_conversion to get nodename
# QNX is used by classic xr and most of other platforms is using Linux

if type node_list_generation >/dev/null 2>&1; then
    node_name=$(node_conversion -N $(node_list_generation -f MY))
else
    node_name=$(uname -n)
fi

fq_nodeid=`node_conversion -i $node_name`


# Get the list of interfaces registered in this node from IM.

# Use the, show  im database location <> view owner, cmd.
# Grep the lines starting with, Interface <interface name in given format>.
# Remove useless stuff
# store list of such interfaces obtained in intf_list_arr, 

# echo $intf_list_arr, for node_0_1_CPU0 may give something like.. /
# GigabitEthernet0/1/0/0 
# GigabitEthernet0/1/0/1 
# GigabitEthernet0/1/0/2
# GigabitEthernet0/1/0/3
# GigabitEthernet0/1/0/4

intf_list_arr=$(im_show "database" "-v" "0x0" "-l" "0x2" "-h" $fq_nodeid | more "-f" | \
	grep -E  "^Interface (Ten|Twenty|Forty|Hundred|Gigabit|Four|Fifty|Two|TwentyFive).*([0-9]+(/[0-9]+)+)(\.[0-9]+)?"| \
	sed 's/,//g' | uniq | cut -d ' ' -f2)

intf_list_arr=$(echo $intf_list_arr |tr '\n' ' '|sed 's/ /#\n/g')

	
# Get the list of interfaces in which we have macsec running.
# These cannot be used directly for passing to client processes.
# Store the interface in the form R/S/I/P  only.
# They will be compared with interfaces on this node obtained from IM

# echo $macsec_interfaces_from_mka, may give something like..
# 0/1/0/0
# 0/1/0/3
# 0/1/0/4
# 0/2/0/0

macsec_interfaces_from_mka=$(show_macsec_mka -m -i all | sed '/^$/d' | \
        sed '/^=/d' | sed -e 's/^[ \t]*//' | sed '/^I/d' | cut -d ' ' -f1 | sed "s/^[a-zA-Z]*//")

macsec_stndby_intf_from_mka=$(show_macsec_mka -m -i all -h | sed '/^$/d' | \
        sed '/^=/d' | sed -e 's/^[ \t]*//' | sed '/^I/d' | cut -d ' ' -f1 | sed "s/^[a-zA-Z]*//")


# Iterate mka list of interfaces and compare with IM interface 
for msc_if in ${macsec_interfaces_from_mka[@]}; do
	msc_if_str=$(echo $intf_list_arr| grep -o "\S*$msc_if#" | sed 's/#//')

	if [[ $msc_if_str ]]; then
	    msc_if_str_internal=`convert_interface_fmt '-i' $msc_if_str`

	    if_stats_exec[i]="show macsec mka statistics interface $msc_if_str"
	    if_stats__ksh[i]="show_macsec_mka -m -t intf -f $msc_if_str_internal"
	    i=$(($i + 1))

	    if_stats_exec[i]="show macsec secy stats interface $msc_if_str"
	    if_stats__ksh[i]="show_macsec_secy -s -f $msc_if_str_internal"
	    i=$(($i + 1))
        fi
done

# Iterate mka list of standby interfaces and compare with IM interface 
for msc_if in ${macsec_stndby_intf_from_mka[@]}; do
	msc_if_str=$(echo $intf_list_arr| grep -o "\S*$msc_if#" | sed 's/#//')

	if [[ $msc_if_str ]]; then
	    msc_if_str_internal=`convert_interface_fmt '-i' $msc_if_str`
            
	    if_stats_exec[i]="show macsec mka standby statistics interface $msc_if_str"
	    if_stats__ksh[i]="show_macsec_mka -m -t intf -f $msc_if_str_internal -h"
	    i=$(($i+1))
        fi
done

if_stats_exec[i]=''
if_stats__ksh[i]=''


macsec_interface_clis() {
   check_platform_type=`get_platform_type`
   if [ -f /pkg/bin/macsec_show_techsupport_fretta ]; then
      enable_techs ""  /pkg/bin/macsec_show_techsupport_fretta
   fi
   if [ -f /pkg/bin/macsec_show_techsupport_asr9k ]; then
      enable_techs ""  /pkg/bin/macsec_show_techsupport_asr9k
   fi
   if [ -f /pkg/bin/macsec_show_techsupport_pd_cmn ]; then
      enable_techs ""  /pkg/bin/macsec_show_techsupport_pd_cmn
   fi

}


# Parse the arguments to the script.
# Usage:
#
#sys.exit()
# A function called display() must be provided that calls the functions to
# Print the output heading
do_show_command() {
     print_main_heading "show tech-support macsec"

     if [ "$__cardtype" == "SYS" ]; then
         exec_commands sys
     else
         case "$__cardtype" in
         "RP"|"DRP")
             exec_commands rp
             exec_commands if_stats
             macsec_interface_clis
             ;;
         "LC")
             if [ -f /pkg/bin/macsec_mka ]
             then
                exec_commands lc
                exec_commands if_stats
                macsec_interface_clis
             fi
	     ;;
         esac
     fi

     # Print the closing heading.
     print_main_heading "show tech-support macsec complete"
}
# The display function.
display() {
        do_show_command
}

  # This function calls the display() function and sends the output to file if
  # the file option has been set.
. /pkg/bin/show_tech_file_fragment
