#!/bin/bash
set +x

G_INSPECT_MMLPATH="/opt/huawei/snas/script/inspect_mml"
[ -f ${G_INSPECT_MMLPATH}/CheckItems ] && source ${G_INSPECT_MMLPATH}/CheckItems
source ${G_INSPECT_MMLPATH}/CommonFunc.sh

#ȡù
function show_all_nic()
{
    ls /etc/sysconfig/network*/ifcfg-* | grep -wv lo | awk -F"ifcfg-" '{print $2}'
}

function is_ib_nic()
{
    local nic=$1
    local RepeatTimes=(1 2 3)

    for time in ${RepeatTimes[*]}; do
        local containIB=$(ethtool -i $nic|grep driver|awk -F: '{print $2}'|sed 's/^ *//g')
        local iRet=$?
        if [ $iRet -eq 75 ]; then
            sleep 10
        else
            break
        fi
    done

    if [ "$containIB" == "ipoib" -o "$containIB" == "ib_ipoib" ]; then
        return 0
    fi
    return 1
}

function is_bond_nic()
{
    local nic=$1
    local IsVlan=""
    local containBond=""
    local RepeatTimes=(1 2 3)

    for time in ${RepeatTimes[*]};do
        local containBond=$(ethtool -i $nic|grep driver|awk -F: '{print $2}'|sed 's/^ *//g')
        local iRet=$?
        if [ $iRet -eq 75 ]; then
            sleep 10
        else
            break
        fi
    done
    IsVlan=$(echo $containBond | grep VLAN)
    if [ "$containBond" = "bonding" -o "$IsVlan" != "" ]; then
        return 0
    fi
    return 1
}

function get_nic_info()
{
    local nic=$1
    local ips=""
    local masks=""
    local prefixs=""
    local ipv6Flag=0
    local if_info=""
    local mac=""
    local rx_info=""
    local tx_info=""
    local nic_cfg="/etc/sysconfig/network*/ifcfg-$nic"
    local ips_tmp=""

    ips_tmp=$(cat $nic_cfg |sed '/REMOTE_IPADDR/'d |grep IPADDR |awk -F= '{print $2}'|awk -F"'" '{print $2}'|sed 's/\/.*//g'|sort -u)
    if_info=$(ifconfig $nic 2>/dev/null)
    for ip in $ips_tmp; do
        ip_matach=$(echo "$if_info" | grep -w "$ip")
        if [ -n "$ip_matach" ]
        then
            ips="$ips $ip"
            #IPv6ʾǰ׺,ipv4ʾ
            echo "$ip" | grep -q ":" > /dev/null
            if [ $? -eq 0 ];then
                #c00 c20 ifconfig汾һ£ʾһ¡
                echo "$ip_matach" | grep -q "/" > /dev/null
                if [ $? -eq 0 ];then
                    prefix=$(echo "$ip_matach" |awk '{print $3}'| awk -F'/' '{print $2}')
                else
                    prefix=$(echo "$ip_matach" |awk '{print $4}')
                fi
                prefixs="$prefixs $prefix"
                ipv6Flag=1
            else
                mask=$(echo "$ip_matach" | awk '{print $4}' | sed 's/.*Mask://g')
                masks="$masks $mask"
            fi
        fi
    done
    #bondip,maskΪ
    ips=${ips:---}
    masks=${masks:---}
    prefixs=${prefixs:---}

    #Ϊÿأǰػһ
    if [ $ipv6Flag -eq 1 ];then
        gw=$(ip -6 route show | grep default | grep $nic | head -1 | awk '{print $3}')
        if [ "$gw" = "::" ] || [ "$gw" = "" ];then
            gw="--"
        fi
    else
        gwinfo=$(route -n|grep UG|grep $nic|awk '{print $1}')
        gw=$(route -n|grep UG|grep $nic|awk '{print $2}')
        if [ "$gwinfo" != "0.0.0.0" ];then
            gw="--"
        fi
    fi

    mac=$(ip address show ${nic} | grep -E "ether|infiniband" | awk '{print $2}')

    #xxxx
    rx_info=$(echo "$if_info" | grep "RX packets" | sed 's/^ *//g')
    tx_info=$(echo "$if_info" | grep "TX packets" | sed 's/^ *//g')

    rx_info=${rx_info:---}
    tx_info=${tx_info:---}
    #ʹù߸ʽ
    echo "IP:$ips||Mask:$masks||Prefix:$prefixs||Gateway:$gw||MAC:$mac||RX:$rx_info||TX:$tx_info"
}

function get_flow()
{
    local nic=$1
    local speed=$2
    local isPass=0
    local rx_flow=""
    local tx_flow=""
    local first=""
    local Now_Flow=""
    local fimename="/tmp/tmpfilert_flow"

    #ȡ
    rx_flow=$(cat $fimename | grep " $nic " | grep Average | awk '{print $5}')
    tx_flow=$(cat $fimename | grep " $nic " | grep Average | awk '{print $6}')

    Now_Flow=$(echo $rx_flow + $tx_flow|bc)

    flow_Usage=0
    if [ "$speed" != "--" ] ;then
        tmp_speed1=$(echo $speed \* 0.8|bc)
        if [ "$tmp_speed1" != "0" ];then
            flow_Usage=$(echo "scale=2;$Now_Flow*100/$tmp_speed1"|bc)
        else
            #Ϣʹ[ERR]ʶ
            isPass=1
        fi
    fi

    first=$(echo ${flow_Usage:0:1})
    if [ "$first" == '.' ];then
        flow_Usage="0${flow_Usage}"
    fi
    echo "rx_flow:$rx_flow||tx_flow:$tx_flow||flow_Usage:${flow_Usage}%"
    return $isPass
}

#һIB
function check_nic()
{
    local nic=$1
    local resultFile=$2
    local status=""
    local iRet=""
    local isPass=0
    local nic_info=""
    local eth_info=""
    local flow_info=""
    local speed=""
    local std_speed=""
    local duplex=""
    local tmp_speed=0
    local tmp_speed1="--"
    local RepeatTimes=(1 2 3)

    for time in ${RepeatTimes[*]};do
        nic_info=$(ethtool $nic)
        iRet=$?
        if [ $iRet -eq 75 ]; then
            sleep 10
        else
            break
        fi
    done

    #link status
    status=$(echo "$nic_info"|grep "Link detected"|awk '{print $3}')
    if [ "$status" = "yes" ]; then
        status="Up"
    else
        echo "[ERR]INFO:$nic Status($status) is not Normal!" >> ${resultFile} 2>&1
        status="Down"
        isPass=1
    fi

    #߼⴦
    is_bond_nic $nic
    if [ $? -eq 0 ]; then
        echo "NetName:$nic||Status:$status||Duplex:--||Speed:--||rx_flow:--||tx_flow:--||flow_Usage:--||IP:--||Mask:--||Prefix:--||Gateway:--||MAC:--||RX:--||TX:--" >> ${resultFile} 2>&1
        return $isPass
    fi

    duplex=$(echo "$nic_info"|grep "Duplex"|awk '{print $2}')
    if [ "$duplex" != "Full" ]; then
        isPass=1
        duplex="${duplex:---}"
        echo "[ERR]INFO:$nic Duplex(${duplex}) not Full!" >> ${resultFile} 2>&1
    fi

    speed=$(echo "$nic_info"|grep "Speed"|awk '{print $2}')
    #56 100 IB
    if [ "$speed" != "1000Mb/s"  ] && [ "$speed" != "10000Mb/s" ] && [ "$speed" != "25000Mb/s" ] && [ "$speed" != "40000Mb/s" ] && [ "$speed" != "100000Mb/s" ] ;then
        isPass=1
        speed="${speed:---}"
        echo "[ERR]INFO:$nic Speed(${speed}) not 1000Mb/s or 10000Mb/s or 25000Mb/s or 40000Mb/s or 100000Mb/s!" >> ${resultFile} 2>&1
    fi
    #ת
    if [ "$speed" != "--" ];then
        tmp_speed=$(echo $speed | awk '{print $1+0}')
        tmp_speed1=$(expr $tmp_speed \* 128)
    fi

    #
    std_speed=$(echo "$nic_info" | grep -B6 "Supports auto-negotiation" |grep Full |  grep -Po '(?<=)[0-9]+' | sort -u -r | head -n 1)
    if [ "$speed" != "--" ] && [ $tmp_speed -lt $std_speed ];then
        echo "[ERR]INFO:$nic rate of ${speed} is less than the physical bandwidth of ${std_speed}Mb/s!" >> ${resultFile} 2>&1
        isPass=$(check_pass $isPass 4)
    fi

    #
    flow_info=$(get_flow $nic ${tmp_speed1})
    if [ $? -ne 0 ];then
        isPass=1
        echo "[ERR]INFO:$nic get Now_Flow failed!" >> ${resultFile} 2>&1
    fi

    #IP MAC Ϣ
    eth_info=$(get_nic_info $nic)
    echo "NetName:$nic||Status:$status||Duplex:$duplex||Speed:${speed}||${flow_info}||${eth_info}" >> ${resultFile} 2>&1

    return $isPass
}


function check_ib()
{
    local ib_port=$1
    local resultFile=$2
    local iRet=0
    local isPass=0
    local mac=""
    local guid=""
    local status=""
    local speed=""
    local duplex="--"
    local tmp_speed1=""
    local flow_info=""
    local eth_info=""
    local ib_info=""


    ib_info=$(ibstat 2>/dev/null)
    iRet=$?
    if [ $iRet -ne 0 ]; then
        isPass=1
        echo "[ERR]INFO:Failed to get ib info from command(ibstat)!" >> ${resultFile} 2>&1
        return $isPass
    fi

    mac=$(cat /sys/class/net/$ib_port/address  | tr -d ":")
    guid=${mac:24:40}
    status=$(ibstat |grep  -B6 "Port GUID: 0x$guid" |grep "Physical state"|awk '{print $3}' 2>/dev/null)
    speed=$(ibstat |grep  -B6 "Port GUID: 0x$guid" |grep "Rate" | awk '{print $2}' 2>/dev/null)

    if [ "$status" = "LinkUp" ];then
        status="Up"
    else
        isPass=1
        echo "[ERR]INFO:IB $ib_port Status($status) is not Normal!" >> ${resultFile} 2>&1
        status="Down"
    fi

    if [ "$speed" = "" ]; then
        echo "[ERR]INFO:No speed info of $ib_port!" >> ${resultFile} 2>&1
        isPass=1
        speed="--"
    fi

    #ת
    if [ "$speed" != "--" ];then
        #xxxxGb/s תΪΪ KB(*1024*1024/8) ,ֵΪ80%
        tmp_speed1=$(expr $speed \* 131072)
    fi

    #
    flow_info=$(get_flow $ib_port $tmp_speed1 )
    if [ $? -ne 0 ];then
        isPass=1
        echo "[ERR]INFO:$ib_port get Now_Flow failed!" >> ${resultFile} 2>&1
    fi
    #IP MAC Ϣ
    eth_info=$(get_nic_info $ib_port)

    echo "NetName:$ib_port||Status:$status||Duplex:$duplex||Speed:${speed}Gb/s||${flow_info}||${eth_info}" >> ${resultFile} 2>&1
    return $isPass
}

isZeroDomain()
{
    local domainID=$(grep SubDomain /opt/huawei/snas/etc/cm.ini|awk -F "=" '{print $2}')
    return $domainID
}

function check_all_nic()
{
    local isPass=0
    local localomnic=""
    local localomnic_v6=""
    local curInspectNum="106"
    local curInspectFun="$(GetInspectType $curInspectNum)"
    local fimename="/tmp/tmpfilert_flow"
    local resultFile="/tmp/tmpResult${curInspectFun}"
    local nics=$(show_all_nic)
    if [ -L ${resultFile} ]; then
        rm -f ${resultFile}
        LOG "[$curInspectFun][$LINENO] There are security risks."
    fi
    >${resultFile}

    #Ϊÿѯһεǰǰִ
    sar -n DEV 1 2 > $fimename

    #set_ifs
    for nic in $nics;
    do
        #0NIC0״̬
        if [[ "$nic" =~ "NIC" ]]; then
            isZeroDomain
            if [ $? -ne 0 ]; then
                LOG "[$curInspectFun][$LINENO] The $nic isn't in subdomian of zero."
                continue;
            fi
            #Ƿǹ
            omnic=$(cat /opt/huawei/snas/etc/cm.ini |grep omCard |awk -F= '{print $2}'|tr -d ' ')
            if [[ "${omnic}" =~ "bond" ]];then
                LOG "[$curInspectFun][$LINENO] The $omnic is match bond. nic is ${nic}"
                local bBondcard=0
                for bondcard in $(cat /etc/sysconfig/network*/ifcfg-${omnic} | grep BONDING_SLAVE | awk -F= '{print $2}'|tr -d ' '|tr -d "'")
                do
                    if [ "X${nic}" = "X${bondcard}" ];then
                        bBondcard=1
                        break;
                    fi
                done
                localomnic=$(cat /opt/huawei/snas/etc/cm.ini |grep -w LocalOMCard |awk -F= '{print $2}'|tr -d ' ')
                localomnic_v6=$(cat /opt/huawei/snas/etc/cm.ini |grep -w LocalOMCard_v6 |awk -F= '{print $2}'|tr -d ' ')

                if [ "${nic}" != "${localomnic}" -a "${nic}" != "${localomnic_v6}" -a ${bBondcard} -ne 1 ];then
                    LOG "[$curInspectFun][$LINENO] The $nic isn't omCard and localOmCard(${localomnic}, ${localomnic_v6})"
                    continue;
                fi
            elif [ "$nic" != "$omnic" ];then
                LOG "[$curInspectFun][$LINENO] The $nic isn't omCard."
                continue;
            fi
        fi

        #жIB, C72ûIB,IB̡
        is_ib_nic $nic
        if [ $? -eq 0 ]; then
            check_ib $nic $resultFile
            iRet=$?
            isPass=$(check_pass $isPass $iRet)
        else
            #IBڵڴ˼
            check_nic $nic $resultFile
            iRet=$?
            isPass=$(check_pass $isPass $iRet)
        fi

    done
    #restore_ifs

    echo "${curInspectFun}_Pass ${isPass}" >>${resultFile} 2>&1

    [ -f "$fimename" ] && rm -f "$fimename"

}

check_all_nic

#Ƿسɹ[ERR]ʶǷ
exit 0

