# IBM(c) 2007 EPL license http://www.eclipse.org/legal/epl-v10.html
#
# Raw commands to set BMCs to defaults
#   dx320
#     0x2e 0x10 0x4d 0x4f 0x00 0xff
#
#   dx340 
#     0x30 0x13 0xff 0x00 0x00 0x00
#
#   dx360/x3450
#     0x30 0x02 0x43 0x4c 0x52 0xaa
#     0x08 0x00 0x49 0x4e 0x54 0x45 0x4c
#     0x08 0x04
#
allowcred.awk &
CREDPID=$!
sleep 5
IPCFGMETHOD=static
while [ -z "$BMCIP" -a $IPCFGMETHOD="static" ]; do
    while ! getipmi
    do
        echo "Retrying retrieval of IPMI settings from server"
    done
    TIMEOUT=15
    BMCIP=`grep bmcip /tmp/ipmicfg.xml |awk -F\> '{print $2}'|awk -F\< '{print $1}'`
    BMCVLAN=`grep taggedvlan /tmp/ipmicfg.xml |awk -F\> '{print $2}'|awk -F\< '{print $1}'`
    if [ -z "$BMCVLAN" ]; then 
        BMCVLAN=off;
    fi
    BMCGW=`grep gateway /tmp/ipmicfg.xml |awk -F\> '{print $2}'|awk -F\< '{print $1}'`
    BMCNM=`grep netmask /tmp/ipmicfg.xml |awk -F\> '{print $2}'|awk -F\< '{print $1}'`
    BMCUS=`grep username /tmp/ipmicfg.xml |awk -F\> '{print $2}'|awk -F\< '{print $1}'`
    BMCPW=`grep password /tmp/ipmicfg.xml |awk -F\> '{print $2}'|awk -F\< '{print $1}'`
    IPCFGMETHOD=`grep ipcfgmethod /tmp/ipmicfg.xml|awk -F\> '{print $2}'|awk -F\< '{print $1}'`
    if [ -z "$IPCFGMETHOD" ]; then
        IPCFGMETHOD="static"
    fi
    if [ -z "$BMCIP" -a $IPCFGMETHOD="static" ]; then
        echo "FAILED TO RETRIEVE SETTINGS, RETRYING in 15 seconds"
        sleep 15
    fi
done
kill $CREDPID
NUMBMCS=`grep bmcip /tmp/ipmicfg.xml |awk -F\> '{print $2}'|awk -F\< '{print $1}'|wc -l`
IPMIVER=`ipmitool mc info|grep ^IPMI|awk  '{print $4}'`
IPMIMFG=`ipmitool mc info|grep "^Manufacturer ID"|awk  '{print $4}'`

if [ "$IPMIMFG" == 2 ]; then #IBM
    XPROD=`ipmitool mc info|grep "^Product ID"|awk '{print $4}'`
    if [ "$XPROD" == "220" ]; then
        LOCKEDUSERS=1
        BMCPORT=`grep bmcport /tmp/ipmicfg.xml |awk -F\> '{print $2}'|awk -F\< '{print $1}'`
        if [ ! -z "$BMCPORT" ]; then
            let idev=0
            IFS=','
            for p in $BMCPORT; do
                ipmitool -d $idev raw 0xc 1 1 0xc0 $p > /dev/null
                ipmitool -d $idev raw 0x04 0x12 0x09 0x01 0x18 0x${p}1 0x00 > /dev/null
                CURBMCPORT=`ipmitool -d $idev raw 0xc 2 1 0xc0 0 0 | awk '{print $2}'`
                while [ "$CURBMCPORT" -ne "$BMCPORT" ]; do
                    sleep 1
                    CURBMCPORT=`ipmitool -d $idev raw 0xc 2 1 0xc0 0 0 | awk '{print $2}'`
                done
                let idev=idev+1
            done
            unset IFS
        fi
    elif [ "$XPROD" == "291" ]; then
        LOCKEDUSERS=1
    else
        IBMFAM=`ipmitool raw 0x3a 0x50 |head -n 1| awk '{print $1 $2 $3 $4}'`
        if [ "$IBMFAM" == "59554f4f" ]; then
            BMCPORT=`grep bmcport /tmp/ipmicfg.xml |awk -F\> '{print $2}'|awk -F\< '{print $1}'`
            if [ ! -z "$BMCPORT" ]; then
                let idev=0
                IFS=','
                for p in $BMCPORT; do
                    ipmitool -d $idev raw 0xc 1 1 0xc0 $p > /dev/null
                    CURBMCPORT=`ipmitool -d $idev raw 0xc 2 1 0xc0 0 0 | awk '{print $2}'`
                    while [ "$CURBMCPORT" -ne "$BMCPORT" ]; do
                        sleep 1
                        CURBMCPORT=`ipmitool -d $idev raw 0xc 2 1 0xc0 0 0 | awk '{print $2}'`
                    done
                    let idev=idev+1
                done
                unset IFS
            fi
        fi
    fi
elif [ "$IPMIMFG" == 20301 -o "$IPMIMFG" == 19046 ] ; then
    XPROD=`ipmitool mc info|grep "^Product ID"|awk '{print $4}'`
    IBMVPDV=`ipmitool raw 0x3a 0xb 2 0 16 1`
    if [ $IBMVPDV -eq 2 ]; then
        ISITE=1;
    fi
        LOCKEDUSERS=1
        BMCPORT=`grep bmcport /tmp/ipmicfg.xml |awk -F\> '{print $2}'|awk -F\< '{print $1}'`
        if [ ! -z "$BMCPORT" ]; then
            let idev=0
            IFS=','
            for p in $BMCPORT; do
                unset IFS
                ipmitool -d $idev raw 0xc 1 1 0xc0 $p > /dev/null
                IFS=','
                # after this change, we need to watch and wait to see that it
                # actually takes effect.  On port change, the service processor
                # does not migrate the network configuration over
                # so we might be halfway through setting up when the net config 
                # reverts to dhcp then static, which setting a static ip for is
                # considered invalid
                CURBMCPORT=`ipmitool -d $idev raw 0xc 2 1 0xc0 0 0 | awk '{print $2}'`
                while [ -z "$CURBMCPORT" -o 0"$CURBMCPORT" -ne "$BMCPORT" ]; do
                    sleep 1
                    CURBMCPORT=`ipmitool -d $idev raw 0xc 2 1 0xc0 0 0 | awk '{print $2}'`
                done
                let idev=idev+1
            done
            unset IFS
        fi
elif [ "$IPMIMFG" == "47488" ]; then
    LOCKEDUSERS=1
fi

echo -n "Auto detecting LAN channel..."
while [ -z "$LANCHAN" ]; do 
    for TLANCHAN in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16; do 
        if ipmitool channel info $TLANCHAN 2> /dev/null | grep 802.3 > /dev/null 2>&1 && ipmitool raw 0xc 2 $TLANCHAN 5 0 0 > /dev/null 2>&1; 
        then 
            LANCHAN=$TLANCHAN
            break; 
        fi; 
        echo -n "."
    done
    if [ -z "$LANCHAN" ]; then
        echo "Unable to detect lan channel, retrying in 10 seconds";
        sleep 10
    fi
done
echo "Detected LAN channel $LANCHAN"
        
let idev=NUMBMCS
if [ $IPCFGMETHOD="static" ]; then
    while [ $idev -gt 0 ]; do
        let idev=idev-1
        TRIES=0
        while ! ipmitool -d $idev lan set $LANCHAN ipsrc static; do
            sleep 1
            let TRIES=TRIES+1
            if [ $TRIES -gt $TIMEOUT ]; then
                break;
            fi
        done
    done
    let idev=0
    for b in $BMCIP; do
        TRIES=0
        while ! ipmitool -d $idev lan set $LANCHAN ipaddr $b; do
            sleep 1
            let TRIES=TRIES+1
            if [ $TRIES -gt $TIMEOUT ]; then
                break;
            fi
        done
        let idev=idev+1
    done
    let idev=0
    for m in $BMCNM; do
        TRIES=0
        while ! ipmitool -d $idev lan set $LANCHAN netmask $m; do
            sleep 1
            let TRIES=TRIES+1
            if [ $TRIES -gt $TIMEOUT ]; then
                break;
            fi
        done
        let idev=idev+1
    done
    TRIES=0
    if [ ! -z "$BMCGW" ]; then
        let idev=0
        for g in $BMCGW; do
            TRIES=0
            while ! ipmitool -d $idev lan set $LANCHAN defgw ipaddr $g; do
                sleep 1
                let TRIES=TRIES+1
                if [ $TRIES -gt $TIMEOUT ]; then
                    break;
                fi
            done
            let idev=idev+1
        done
        TRIES=0
    fi
else
    let idev=NUMBMCS
    while [ $idev -gt 0 ]; do
        let idev=idev-1
        TRIES=0
        while ! ipmitool -d $idev lan set $LANCHAN ipsrc $IPCFGMETHOD; do
            sleep 1
            let TRIES=TRIES+1
            if [ $TRIES -gt $TIMEOUT ]; then 
                break;
            fi
        done
    done
fi

let idev=0
for b in $BMCVLAN; do
    TRIES=0
    while ! ipmitool -d $idev lan set $LANCHAN vlan id $b; do
        sleep 1
        let TRIES=TRIES+1
        if [ $TRIES -gt $TIMEOUT ]; then 
            break;
        fi
    done
    let idev=idev+1
done

let idev=NUMBMCS-1
for bmcu in $BMCUS; do
    if [ "$bmcu" = "" ]; then continue; fi
DISABLEUSERS="1 2 3 4"
if [ ! -z "$LOCKEDUSERS" ]; then
    USERSLOT=`ipmitool -d $idev user list $LANCHAN |grep -v ^ID|awk '{print $1 " " $2}'|grep -w "$BMCUS"|awk '{print $1}'`
    if [ -z "$USERSLOT" ]; then
        USERSLOT=4
    fi
else
    USERSLOT=2
fi
if [ "$ISITE" = 1 ]; then
    allowcred.awk &
    CREDPID=$!
    while ! remoteimmsetup
    do
        echo "Waiting for xCAT remote configuration of service processor via CMM.."
    done
    kill $CREDPID
fi
CURRENTUSER=`ipmitool -d $idev user list $LANCHAN|grep ^$USERSLOT|awk '{print $2}'`
DISABLEUSERS=`echo 1 2 3 4|sed -e s/$USERSLOT//`
for user in $DISABLEUSERS; do
    while ! ipmitool -d $idev user disable $user; do
        sleep 1
        let TRIES=TRIES+1
        if [ $TRIES -gt $TIMEOUT ]; then break; fi
    done
    TRIES=0
done
TRIES=0
while ! ipmitool -d $idev user enable $USERSLOT; do
    sleep 1
    let TRIES=TRIES+1
    if [ $TRIES -gt $TIMEOUT ]; then break; fi
done
TRIES=0
# Last param in ipmitool user priv is the channel to set it on.
# Penguin boxes are all channel 2
CURRPRIV=`ipmitool -d $idev user list $LANCHAN|grep ^$USERSLOT|awk '{print $6}'`
if [ "$CURRPRIV" != "ADMINISTRATOR" ]; then 
    while ! ipmitool -d $idev user priv $USERSLOT 4 $LANCHAN; do
        sleep 1
        let TRIES=TRIES+1
    if [ $TRIES -gt $TIMEOUT ]; then break; fi
    done
    TRIES=0
fi
TRIES=0
while ! ipmitool -d $idev channel setaccess $LANCHAN $USERSLOT link=on; do
    sleep 1
    let TRIES=TRIES+1
    if [ $TRIES -gt $TIMEOUT ]; then break; fi
done
TRIES=0
if [ "$CURRENTUSER" != "$bmcu" ]; then
    while ! ipmitool -d $idev user set name $USERSLOT $bmcu; do
        sleep 1
        let TRIES=TRIES+1
        if [ $TRIES -gt $TIMEOUT ]; then break; fi
    done
fi
let idev=idev-1
done
let idev=NUMBMCS-1
for bmcp in $BMCPW; do
    if [ "$bmcp" = "" ]; then continue; fi
TRIES=0
while ! ipmitool -d $idev user set password $USERSLOT $bmcp; do
    sleep 1
    let TRIES=TRIES+1
    if [ $TRIES -gt $TIMEOUT ]; then break; fi
done
TRIES=0
echo "Set up following user table: "
ipmitool -d $idev user list $LANCHAN
let idev=idev-1
done

let idev=NUMBMCS
while [ $idev -gt 0 ]; do
let idev=idev-1


echo -n "Enabling Channel $LANCHAN: "
while ! ipmitool -d $idev raw 0x6 0x40 $LANCHAN 0x42 0x44 > /dev/null; do
    sleep 1
    let TRIES=TRIES+1
    if [ $TRIES -gt $TIMEOUT ]; then break; fi
done
TRIES=0
while ! ipmitool -d $idev raw 0x6 0x40 $LANCHAN 0x82 0x84 > /dev/null; do
    sleep 1
    let TRIES=TRIES+1
    if [ $TRIES -gt $TIMEOUT ]; then break; fi
done
if [ $TRIES -gt $TIMEOUT ]; then echo "ERROR"; else echo "OK"; fi
TRIES=0

echo -n "Enabling ARP responses: "
while ! ipmitool -d $idev lan set $LANCHAN arp respond on > /dev/null; do
    sleep 1
    let TRIES=TRIES+1
    echo -n .
    if [ $TRIES -gt $TIMEOUT ]; then break; fi
done
if [ $TRIES -gt $TIMEOUT ]; then echo "ERROR"; else echo "OK"; fi
TRIES=0

echo -n "Enabling IPMI v 1.5 MD5 LAN access:"
while ! ipmitool -d $idev lan set $LANCHAN auth admin md5 > /dev/null; do
    sleep 1
    let TRIES=TRIES+1
    if [ $TRIES -gt $TIMEOUT ]; then break; fi
done
if [ $TRIES -gt $TIMEOUT ]; then echo "ERROR"; else echo "OK"; fi
TRIES=0
if [ ! "$IPMIVER" == "1.5"  ]; then 
    echo -n "Enabling IPMI v 2.0 LAN access: "
    #the following goals:
    #disable cipher suite 0 (if present, avoid password bypass)
    #disable cipher suite 1 (if present, to avoid weaking Kg if used)
    #enable cipher suite 2 (scenarios without perl Rijndael)
    #enable cipher suite 3
    #ignore the rest
    ZEROIDX=$(ipmitool lan print $LANCHAN|grep ^RMCP+|cut -d: -f 2|sed -e 's/ //' -e 's/,/\n/g'|grep -n '%0$'|sed -e 's/:.*//')
    ONEIDX=$(ipmitool lan print $LANCHAN|grep ^RMCP+|cut -d: -f 2|sed -e 's/ //' -e 's/,/\n/g'|grep -n '^1$'|sed -e 's/:.*//')
    TWOIDX=$(ipmitool lan print $LANCHAN|grep ^RMCP+|cut -d: -f 2|sed -e 's/ //' -e 's/,/\n/g'|grep -n '^2$'|sed -e 's/:.*//')
    THREEIDX=$(ipmitool lan print $LANCHAN|grep ^RMCP+|cut -d: -f 2|sed -e 's/ //' -e 's/,/\n/g'|grep -n '^3$'|sed -e 's/:.*//')
    ACCESS=$(ipmitool lan print $LANCHAN|grep 'Cipher Suite Priv Max'|cut -d: -f 2|sed -e 's/ //g' -e 's/\(.\)/\1\n/g'|grep -v '^$')
    NEWACCESS=""
    i=1
    for elem in $ACCESS; do
        if [ $i = "$ZEROIDX" -o $i = "$ONEIDX" ]; then
            NEWACCESS="$NEWACCESS"X
        elif [ $i = "$TWOIDX" -o $i = "$THREEIDX" ]; then
            #do not *downgrade* from OEM priv
            if [ "$elem" != "O" ]; then NEWACCESS="$NEWACCESS"a; else NEWACCESS="$NEWACCESS"$elem; fi
        else
            NEWACCESS="$NEWACCESS"$elem
        fi
        i=$((i+1))
    done
    if ipmitool lan set $LANCHAN cipher_privs $NEWACCESS > /dev/null; then
        echo OK
    else
        echo ERROR
    fi

    TRIES=0
    echo -n "Enabling SOL for channel $LANCHAN:"
    while ! ipmitool -d $idev raw 0xc 0x21 $LANCHAN 0x1 0x1 > /dev/null; do
        sleep 1
        let TRIES=TRIES+1
        if [ $TRIES -gt $TIMEOUT ]; then break; fi
    done
    if [ $TRIES -gt $TIMEOUT ]; then echo "ERROR"; else echo "OK"; fi
    TRIES=0
    
    echo -n "Enabling SOL for $BMCUS:"
    while ! ipmitool -d $idev raw 6 0x4c $LANCHAN $USERSLOT 2 0 0 0 > /dev/null; do
        sleep 1
        let TRIES=TRIES+1
        if [ $TRIES -gt $TIMEOUT ]; then break; fi
    done
    if [ $TRIES -gt $TIMEOUT ]; then echo "ERROR"; else echo "OK"; fi
    
    # 0xc 0x21 with data 7 is used to set payload channel, it is readonly in the ipmiv2.0 doc, so comment this section out.
    #echo -n "Putting SOL on channel $LANCHAN:"
    #while ! OUTPUT=`ipmitool -d $idev raw 0xc 0x21 $LANCHAN 7 $LANCHAN 2>&1 > /dev/null`; do
    #	if echo $OUTPUT|grep "Unknown (0x80)" > /dev/null; then
    #		echo "Not Needed"
    #		break
    #    fi
    #    sleep 1
    #    let TRIES=TRIES+1
    #    if [ $TRIES -gt $TIMEOUT ]; then break; fi
    #done
    #if [ $TRIES -gt $TIMEOUT ]; then echo "ERROR"; else echo "OK"; fi
fi

#
# Cold Reset the BMC for: 
#    Product ID: 309   - x3755 M4 (8722)
#    Product ID: 43707 - IBM Power S822LC and S812LC
# Otherwise the BMC will not respond to ping after running bmcsetup 
#
XPROD=`ipmitool mc info|grep "^Product ID"|awk '{print $4}'`
if [ "$XPROD" = "309" -o "$XPROD" = "43707" ] ; then
    if [ "$XPROD" = "43707" ]; then
        # The IBM Power S822LC and S812LC should NOT need a reset to apply changes
        # to the BMC.  However, it seems there's a problem with the BMC where after
        # 15 seconds, it stops responding.  To work around until the firmware is fixed,
        # have a sleep here for 30 seconds, then issue the reset of the BMC 
        sleep 30
    fi
    echo "Resetting BMC ..."
    ipmitool mc reset cold
    echo "Waiting for the BMC to appear ..."
    sleep 15
    TRIES=0
    while ! ipmitool lan print $LANCHAN > /dev/null; do
        sleep 3
        let TRIES=TRIES+1
        if [ $TRIES -gt $TIMEOUT ]; then break; fi
    done
fi

# update the node status to 'bmcready'
for parm in `cat /proc/cmdline`; do
    key=`echo $parm|awk -F= '{print $1}'`
    if [ "$key" = "xcatd" ]; then
        XCATMASTER=`echo $parm|awk -F= '{print $2}'|awk -F: '{print $1}'`
    fi
done
if [ ! -z "$XCATMASTER" ]; then
    updateflag.awk $XCATMASTER 3002 "installstatus bmcready"
fi

echo "Lighting Identify Light"
while :
    do ipmitool -d $idev raw 0 4 10 > /dev/null
    sleep 7
done &
done

