#! /pkg/bin/ksh
# Created by Noritake Izaiku Nov 2008
# Copyright (c) 2008-2009, 2013-2020 by cisco Systems, Inc.
# All rights reserved.
#
#----------------------------------------------------------------------

. /pkg/bin/show_tech_main_fragment

NETFLOW_DEBUG=false
# set NETFLOW_DEBUG=true to enable debug lines
# NETFLOW_DEBUG=true

if [ $NETFLOW_DEBUG = true ]
then 
    debug_echo() { echo "DEBUG: " $* >&2; }
else
    debug_echo() { :; }
fi

# Cardtype indicates the card-type we're running on
# Password flag to indicate whether log will include pw or not
__cardtype="unspecified"
__password="FALSE"

# Parse the arguments to the script.
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

debug_echo "__cardtype=$__cardtype"
debug_echo "__filename=$__filename"
debug_echo "platform=$platform"


# Adds a command to execute to the end of the given list type.
# The first param is the list type, the second is the name of the command,
# and the third is the command to be executed in the shell.
nf_add_cmd()
{
    nf_type=$1

    debug_echo "$2"

    exec_name=${nf_type}_exec
    ksh_name=${nf_type}__ksh
    count_name=count_${nf_type}

    eval count=\$$count_name

    eval ${exec_name}[$count]\=\$2
    eval ${ksh_name}[$count]\=\$3

    eval $count_name'=$(($'$count_name' + 1))'
}


# Adds process info to the list of commands to execute
# $1 is the type (e.g. rp/lc), $2 is the name of the program
nf_add_process()
{
    nf_add_cmd $1 "show process $2" "sysmgr_show -o -p $2"
}


# find the process ID given the name of the process
find_pid()
{
    sysmgr_show -o -p $1 | grep -e PID | cut -c 27-
}

# Follow a process, if it is running
nf_follow()
{
    nf_type=$1
    nf_prog=$2

    nf_pid=`find_pid $nf_prog`
    debug_echo "$nf_prog pid: $nf_pid"
    if [ "$nf_pid" != "" ]
    then
	nf_add_cmd $nf_type \
	    "follow process $nf_pid verbose iteration 1 [$nf_prog]" \
	    "attach_process -p $nf_pid -v -i 1"
    fi
}


# print a summary of commands that will be executed
nf_summary()
{
    nf_type=$1
    nf_upper_type=$2
    exec_name=${nf_type}_exec
    echo "Summary $nf_upper_type -----------------------------------"
    i=1
    while :
    do
	eval name=\${$exec_name[i]}
	if [ "$name" = "" ]
	then
	    break
	fi
	name=$(eval "echo $name")
	echo "    $name"
        i=$(($i + 1))
    done
}


# List each set of show commands to be run. Each set must finish with an empty
# string. Note that for commands which contain variables which are expanded
# later, it is important to use single quotes rather than double quotes
# for the strings containing your commands.
# Use "\" ahead of any special character (eg. |) used in the command line.

# Commands that run on once per system
nf_init_sys()
{
    sys_exec[1]='show version'
    sys_exec[2]='show install active'
    if [ "$platform" = "panini" ]
    then
	sys__ksh[1]='ng_show_version'
	sys__ksh[2]='sdr_instcmd show install active'
    else
	sys__ksh[1]='show_version'
	sys__ksh[2]='instcmd show install active'
    fi
    sys_exec[3]='show running-config'
    sys__ksh[3]='nvgen -c -l 1 -t 1 -o 1'
    sys__ksh[4]=''
}


# Commands that run on all nodes
nf_init_all()
{
    all_exec[1]='show process blocked'
    if [ "$platform" = "panini" ]
    then
	all__ksh[1]='sh_proc_ng_blocked'
    else
	all__ksh[1]='show_processes -b'
    fi
    all_exec[2]='show flow trace all'
    all__ksh[2]='show_flow_ltrace -T all'
    all__ksh[3]=''
}


# Commands that run on all RPs & DRPs
nf_init_rp()
{
    count_rp=1
    debug_echo "Initialising for rp"

    nf_add_cmd rp 'run nf_im_show_trace' \
	'nf_im_show_trace'

    nf_add_cmd rp 'show flow internal mgr' 'nfmgr_cli -t 0x4'

    nf_add_process rp nfmgr
    nf_add_process rp nfma

    nf_follow rp nfmgr
    nf_follow rp nfma

    debug_echo "Getting flow exporter-map configuration"
    femall=`nvgen -c -l 1 -t 1 -o 1 2>/dev/null | \
	grep -E "^flow exporter-map" | cut -c 19-`
    debug_echo "--- FEM ---"
    debug_echo "$femall"
    for femname in $femall
    do
	nf_add_cmd rp "show flow exporter-map $femname" \
	    "nfmgr_cli -t 0x3 -f $femname"
    done

    debug_echo "Getting flow monitor-map configuration"
    fmmall=`nvgen -c -l 1 -t 1 -o 1 2>/dev/null | \
	grep -E "^flow monitor-map" | cut -c 18-`
    debug_echo "--- FMM ---"
    debug_echo "$fmmall"
    for fmmname in $fmmall
    do
	nf_add_cmd rp "show flow monitor-map $fmmname" \
	    "nfmgr_cli -t 0x1 -f $fmmname"
    done

    debug_echo "Getting sampler-map configuration"
    fsmall=`nvgen -c -l 1 -t 1 -o 1 2>/dev/null | \
	grep -E "^sampler-map" | cut -c 13-`
    debug_echo "--- FSM ---"
    debug_echo "$fsmall"
    for fsmname in $fsmall
    do
        nf_add_cmd rp "show sampler-map $fsmname" \
	    "nfmgr_cli -t 0x2 -f $fsmname"
    done

    # Identify the type of the platform
    echo -n "Found Platform Type: "
    echo $platform
    if [ "$platform" == "hfr" ] ; then
        nf_add_cmd rp "show platform" "shelfmgr_show_hfr -e" 
    elif [ "$platform" == "viking" ] ; then
        nf_add_cmd rp "show platform" "show_platform_vkg -e" 
    elif [ "$platform" == "panini" ] ; then
        nf_add_cmd rp "show platform" "show_platform_sysdb" 
    elif [ "$platform" == "fretta" ] ; then
        nf_add_cmd rp "show platform" "show_platform_sysdb"
    else
        nf_add_cmd rp "show platform" "show_platform" 
    fi

    rp__ksh[$count_rp]=''
}


# show command for netflow PD for HFR
nf_lc_platform_cmd_hfr()
{

    nf_add_cmd lc 'show flow platform producer statistics' \
	'show_nf_producer -l $fq_nodeid'
    nf_add_cmd lc 'show flow platform pse policer-rate' \
	'show_nf_hfr_pse -i $fq_nodeid'
}


# show command for netflow PD for Panini
nf_lc_platform_cmd_panini()
{
    nf_add_cmd lc 'show flow platform producer statistics' \
	'show_nf_producer -l $fq_nodeid'
    nf_add_cmd lc 'show flow platform producer nh' \
	'show_nf_producer -n $fq_nodeid'
    nf_add_cmd lc 'show flow platform pse policer-rate' \
	'show_nf_sse_pse -i $fq_nodeid'
}


# show command for netflow PD for Fretta
nf_lc_platform_cmd_fretta()
{
    nf_add_cmd lc 'show flow platform pse policer-rate' \
	'show_nf_dpa_pse -l $fq_nodeid'
}

# show command for netflow PD for Spitfire
nf_lc_platform_cmd_spitfire()
{
    nf_add_cmd lc 'show flow platform producer statistics' \
        'show_nf_producer -l $fq_nodeid'
    nf_add_cmd lc 'show flow platform producer internal' \
        'show_nf_producer -2 $fq_nodeid'
    nf_add_cmd lc 'show flow platform producer statistics internal' \
        'show_nf_producer -3 $fq_nodeid'
    nf_add_cmd lc 'show nfea trace all' \
        'show_nfea_dpa_trace -A'
}

# show command for netflow PD for Viking
nf_lc_platform_cmd_viking() {

    nf_add_cmd lc 'show flow platform nfea samp detail' \
	'nfea_pd_debug_show_cmd -n $fq_nodeid -t -s'
    nf_add_cmd lc 'show flow platform nfea sp' \
	'nfea_pd_debug_show_cmd -n $fq_nodeid -p'

    j=0
    while [ $j -lt 8 ]
    do
	nf_add_cmd lc "show flow platform nfea policer np $j" \
	    "nfea_pd_debug_show_cmd -r -c $j -n \$fq_nodeid"
	j=$(($j + 1))
    done

    j=0
    while [ $j -lt 3 ]
    do
	nf_add_cmd lc "show flow platform nfea chkpt $j all" \
	    "nfea_pd_debug_show_cmd -k $j -o 0 -n \$fq_nodeid"
	j=$(($j + 1))
    done
}


# Commands that run on all LCs
nf_init_lc()
{
    count_lc=1
    debug_echo "Initialising for lc"

    nf_add_cmd lc 'run nf_im_show_trace' \
	'nf_im_show_trace'

    nf_add_process lc nfma
    nf_add_process lc nfea
    nf_add_process lc nfsvr

    nf_follow lc nfma
    nf_follow lc nfea
    nf_follow lc nfsvr

    pid_nf_producer=
    producer_name=
    if [ -f /pkg/bin/nf_producer ]
    then
	producer_name=nf_producer
    fi
    if [ -f /pkg/bin/pse_fam ]
    then
	producer_name=pse_fam
    fi
    if [ "$producer_name" ]
    then
	nf_add_process lc $producer_name
	nf_follow lc $producer_name
    fi

    # Identify the type of the platform
    nf_platform_type=`get_platform_type`
    echo -n "Found Platform Type: "
    echo $nf_platform_type

    if [ "$nf_platform_type" == "HFR" ] || [ "$nf_platform_type" == "CRS" ]; then
        nf_lc_platform_cmd_hfr 
    elif [ "$nf_platform_type" == "ASR9k" ] || [ "$nf_platform_type" == "ASR9K" ]; then
        nf_lc_platform_cmd_viking 
    elif [ "$nf_platform_type" == "PANINI" ]; then
        nf_lc_platform_cmd_panini 
    elif [ "$nf_platform_type" == "FRETTA" ]; then
        nf_lc_platform_cmd_fretta 
    elif [ "$nf_platform_type" == "8000" ]; then
        nf_lc_platform_cmd_spitfire
    else
        echo "No Platform specific commands to be run."
    fi

    nf_add_cmd lc 'show flow exporter' 'nfsvr_show_exporter -A -l $fq_nodeid'
    nf_add_cmd lc 'show flow monitor' 'nfsvr_show_cache -B -h $fq_nodeid'
    nf_add_cmd lc 'show flow monitor cache' 'nfsvr_show_cache -S -A -h $fq_nodeid'
    nf_add_cmd lc 'show flow monitor cache internal' 'nfsvr_show_cache -I -A -h $fq_nodeid'
    nf_add_cmd lc 'IRP data' 'nfsvr_show_irp'
    nf_add_cmd lc 'show flow internal statistics' 'nfsvr_show_statistics -l $fq_nodeid'

    lc__ksh[$count_lc]=''
}


display_sys()
{
    nf_init_sys
    nf_summary sys SYS
    exec_commands sys
}


display_rp()
{
    nf_init_all
    nf_init_rp

    nf_summary all ALL
    nf_summary rp RP

    exec_commands all
    exec_commands rp
}


display_lc()
{
    nf_init_all
    nf_init_lc

    nf_summary all ALL
    nf_summary lc LC

    exec_commands all
    exec_commands lc
}


# A function called display() must be provided that calls the functions to 
# run the required show commands. The display() function is called in 
# /pkg/bin/show_tech_file_fragment

display()
{
    # Print the output heading 
    print_main_heading "show tech-support netflow"

    # Print the specific commands
    case "$__cardtype" in
    SYS)    display_sys ;;
    RP|DRP) display_rp ;;
    LC)	    display_lc ;;
    esac

    # Print the closing heading. 
    print_main_heading "show tech-support netflow complete"
}


# 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
