#!/bin/bash
#
# Usage -A | -i <interface> [ -f file name | -d dir_name ]
#
# Script to generate equivalent of /proc info previously
# Being generated by network drivers
# $Revision: 1.40 $

ioption=0
foption=0
doption=0
Aoption=0
multiport=0
# For test purposes, use junk paths
#INTEL_PROC_DIR=/proc/net/nothing
#BCOM_PROC_DIR=/proc/net/nothing
INTEL_PROC_DIR=/proc/net/PRO_LAN_Adapters
BCOM_PROC_DIR=/proc/net/nicinfo
INTEL_VMWARE_PROC_DIR=/proc/vmware/vmkdev/net/PRO_LAN_Adapters
BCOM_VMWARE_PROC_DIR=/proc/vmware/vmkdev/net/nicinfo

if [ "$MIN_ETHTOOL_VER_REQ" = "" ]
then
   MIN_ETHTOOL_VER_REQ="1.8"
   if [ -e /etc/SuSE-release ]
     then
     SUSE_8=`cat /etc/SuSE-release | grep "SLES-8"`
     if [ "$SUSE_8" != "" ]
       then
       MIN_ETHTOOL_VER_REQ="1.6"
     fi
   fi
fi

INSTALLED_ETHTOOL=`which ethtool 2>/dev/null`
if [ "$?" == "0" ]
then
   INSTALLED_VERSION=`$INSTALLED_ETHTOOL 2>&1 |grep "ethtool version" | cut -d" " -f3`
   if [ -n $INSTALLED_VERSION ] && 
      [ ! "$INSTALLED_VERSION" \< "$MIN_ETHTOOL_VER_REQ" ]
   then
      # we have a good ethtool version
      LOCAL_ETHTOOL=$INSTALLED_ETHTOOL
   elif [ "$ETHTOOL_PATH" = "" ]
   then
         # no user over-ride and old version of ethtool installed.
         # if user over-ride given, we don't check version as that ethtool
         # version may have been patched...
         echo "------------------------------------------------------------"
         echo "Ethtool version $MIN_ETHTOOL_VER_REQ or later is required,"
         echo "install the latest version from the following URL:"
         echo ""
         echo "http://sourceforge.net/projects/gkernel/"
         echo "------------------------------------------------------------"
         exit 1
   fi
fi

# use user specified ethtool if set; if not set and local ethtool
# version is >=1.8, use it; otherwise use our private copy.
ETHTOOL=${ETHTOOL_PATH:-$LOCAL_ETHTOOL}

usage()
{
hpetfe_version=`echo '$Revision: 1.40 $' | cut -d' ' -f 2`
printf "\nhpetfe version %s\n" "$hpetfe_version"

echo "Usage: $0 [<switches>]"
printf "\n"
echo "-i <interface>  Specifies the ethernet interface "
echo "-f <file>       Specifies the file in which the output is saved"
echo "-d <dir>        Specifies the directory in which files named"
echo "                  ethX.info are saved for each ethernet interface"
echo "                  specified by the -i option."
echo "-A              Use all ethernet interfaces on the system"
printf "\n"

echo "Note: -i or -A option should be specified"
echo "Note: -f and -d are mutually Exclusive"
printf "\n"
}


# convert a hex value to an int (i.e. ff to 255)
hex_to_int()
{
   local n=$1
   local ret=0
   local base=1

   local prefix
   local lowdigit_a
   local lowdigit_b

   while [ $n ]; do
      prefix=${n%[0-9a-fA-F]}
      lowdigit_a=${n#$prefix}
      if [ ! $lowdigit_a ]; then
         echo "error in value"
         return 0
      fi
      lowdigit_b=$lowdigit_a
      case $lowdigit_a in
         a|A)   lowdigit_b=10 ;;
         b|B)   lowdigit_b=11 ;;
         c|C)   lowdigit_b=12 ;;
         d|D)   lowdigit_b=13 ;;
         e|E)   lowdigit_b=14 ;;
         f|F)   lowdigit_b=15 ;;
      esac
      ret=$[$ret + $[$lowdigit_b*$base]]
      base=$[$base*16]
      n=$prefix
   done
        
   echo $ret
}


# take a MAC in XX:XX:XX:XX:XX:XX format and
# add 1, returning the same format
incr_mac ()
{
        local n=$1

        n=`echo $n | sed 's/://g'`
        
        ret=`hex_to_int $n`
        
        if [ $ret -gt 281474976710654 ]; then
           ret="00:00:00:00:00:00"
        else
          #add 1
          ret=$[$ret+1]
          #convert back to hex MAC format
          ret=`printf "%012x" $ret | sed 's/[0-9a-fA-F][0-9a-fA-F]/& /g' | awk '{printf "%s:%s:%s:%s:%s:%s",$1,$2,$3,$4,$5,$6}'`
        fi
        
        echo $ret
}

check_for_errors()
{
if [ "$ioption" = "0" -a "$Aoption" = "0" ]
then
	usage
	exit 1
fi

if [ "$ioption" = "1" -a "$Aoption" = "1" ]
then
        echo "Error!! -i and -A options cannot be used together"
	usage
	exit 1
fi

if [ "$foption" = "1" -a "$doption" = "1" ]
then
  echo "Error!! -f and -d options cannot be used together"
  usage
  exit 1
fi

if [ "$foption" = "1" ]
then
  if [ -f $fname -a ! -w $fname ]
  then
   echo "Error!! $fname Exists or Write permission denied. Exiting"
   exit 1
  fi
fi
if [ "$doption" = "1" ]
then
  mkdir -p $dirname
  if [ ! -d $dirname ]
  then
   echo "Error!! Error in creating $dirname. Exiting"
  exit 1
  fi
  if [ ! -w $dirname ]
  then
   echo "Error!! $dirname Exists. Write permission denied. Exiting"
  exit 1
  fi
fi

#Verify for proper interface name

if [ "$ioption" = "1" -a "$Aoption" = "1" ]
then
  echo "Error!! -i and -A options cannot be used together. Exiting"
  exit 1
fi

if [ "$ioption" == "0" -a "$Aoption" == "0" ]
then
   usage
   exit 1
fi
}


check_for_ethtool_ver()
{

if [ -z $ETHTOOL ] || [ ! -f "$ETHTOOL" ]
then
  if [ -d /etc/vmware ]
  then
    if [ -d $INTEL_PROC_DIR ] ||
       [ -d $BCOM_PROC_DIR ] ||
       [ -d $INTEL_VMWARE_PROC_DIR ] ||
       [ -d $BCOM_VMWARE_PROC_DIR ]       
    then
      return 0
    fi
  fi

  echo "------------------------------------------------------------"
  echo "It appears the ethtool application is not installed on"
  echo "this system, or version $MIN_ETHTOOL_VER_REQ or later is"
  echo "not installed. Install the latest version from the following URL:"
  echo ""
  echo "http://sourceforge.net/projects/gkernel/"
  echo "------------------------------------------------------------"
  exit 1
fi

}

display_entry()
{
variable="$1"
varvalue="$2"

if [ "$variable" = "Speed" ] || [ "$variable" = "Duplex" ] || [ "$variable" = "Link" ]
then
	printf "%-25s %s\n" "$variable" "$varvalue"
	return 0
fi

# empty hex values come in a "0x"
if [ "$varvalue" = "" ] || [ "$varvalue" = "N/A" ] || [ "$varvalue" = "0x" ]
then
	return 1
else
	printf "%-25s %s\n" "$variable" "$varvalue"
fi
}

display_static_proc()
{
display_entry "Description" "$descr"
display_entry "Driver_Name" "$drvname"
display_entry "Driver_Version" "$drvversion"
display_entry "PCI_Vendor" "0x$pcivendor"
display_entry "PCI_Device_ID" "0x$pcidevice"
display_entry "PCI_Subsystem_Vendor" "0x$pcisubsys"
display_entry "PCI_Subsystem_ID" "0x$pcisubdev"
display_entry "PCI_Revision_ID" "0x$pcirevid"
display_entry "PCI_Bus" "$busnum"
display_entry "PCI_Slot" "$slotnum"
display_entry "IRQ" "$irq"
display_entry "Memory" "0x$memory"
display_entry "Part_Number" "$partno"
display_entry "System_Device_Name" "$iname"
display_entry "Current_HWaddr" "$caddr"
display_entry "Permanent_HWaddr" "$phwaddr"
printf "\n"
}

get_basic_stats()
{
   iface="$1"

   rx_bytes=0
   rx_packets=1
   rx_errors=2
   rx_dropped=3
   rx_fifo_errors=4
   rx_frame_errors=5
   rx_compressed=6
   rx_multicast=7

   tx_bytes=8
   tx_packets=9
   tx_errors=10
   tx_dropped=11
   tx_fifo_errors=12
   collisions=13
   tx_carrier_errors=14
   tx_compressed=15

   err=1
   if [ -f /proc/net/dev ]
   then
      declare -a nic_stats
      nic_stats=(`cat /proc/net/dev|grep "$iface:"|cut -d: -f2`)
      num_stats=${#nic_stats[*]}

      if [ $num_stats -eq 16 ]
      then
         err=0
         display_entry "Rx_Bytes"           ${nic_stats[$rx_bytes]}
         display_entry "Rx_Packets"         ${nic_stats[$rx_packets]}
         display_entry "Rx_Errors"          ${nic_stats[$rx_errors]}
         display_entry "Rx_Dropped"         ${nic_stats[$rx_dropped]}
         display_entry "Rx_FIFO_Errors"     ${nic_stats[$rx_fifo_errors]}
         display_entry "Rx_Frame_Errors"    ${nic_stats[$rx_frame_errors]}
         display_entry "Rx_Compressed"      ${nic_stats[$rx_compressed]}
         display_entry "Multicast"          ${nic_stats[$rx_multicast]}
         display_entry "Tx_Bytes"           ${nic_stats[$tx_bytes]}
         display_entry "Tx_Packets"         ${nic_stats[$tx_packets]}
         display_entry "Tx_Errors"          ${nic_stats[$tx_errors]}
         display_entry "Tx_Dropped"         ${nic_stats[$tx_dropped]}
         display_entry "Tx_FIFO_Errors"     ${nic_stats[$tx_fifo_errors]}
         display_entry "Collisions"         ${nic_stats[$collisions]}
         display_entry "Tx_Carrier_Errors"  ${nic_stats[$tx_carrier_errors]}
         display_entry "Tx_Compressed"      ${nic_stats[$tx_compressed]}

         # Rx_Length_Errors
         # Rx_Over_Errors
         # Rx_CRC_Errors
         # Rx_Missed_Errors
         # Tx_Aborted_Errors
         # Tx_Heartbeat_Errors
         # Tx_Window_Errors
      fi

   fi

   if [ $err -eq 1 ]
   then
      echo "WARNING: unable to read/parse basice stats from /proc/net/dev"
      echo "         for interface $interface"
   fi
}


display_dynamic_proc()
{
# Print the Statistics
display_entry "Link" "$link"
display_entry "Speed" "$speed"
display_entry "Duplex" "$duplex"
display_entry "State" "$state"
display_entry "Auto_Negotiate" "$auto_negotiate"
display_entry "Speed_Advertisement" "$speed_advertisement"
printf "\n"
printf "\n"
display_entry "Rx_Packets" "$rxpack"
display_entry "Tx_Packets" "$txpack"
display_entry "Rx_Bytes" "$rxbytes"
display_entry "Tx_Bytes" "$txbytes"
display_entry "Rx_Errors" "$rxerrors"
display_entry "Tx_Errors" "$txerrors"
printf "\n"
printf "\n"
display_entry "Rx_CRC_Errors" "$rx_crc_errors"
display_entry "Tx_Carrier_Errors" "$tx_carrier_errors"
display_entry "Tx_Abort_Excess_Coll" "$tx_abort_excess_coll"
display_entry "Tx_Abort_Late_Coll" "$tx_abort_late_coll"
display_entry "Tx_Deferred_Ok" "$tx_deferred_ok"
display_entry "Tx_Single_Coll_Ok" "$tx_single_coll_ok"
display_entry "Tx_Multi_Coll_Ok" "$tx_multi_coll_ok"
display_entry "Rx_Short_Length_Errors" "$rx_short_length_errors"
display_entry "Rx_Long_Length_Errors" "$rx_long_length_errors"
display_entry "Rx_Align_Errors" "$rx_align_errors"

# if the driver doesn't provide all the stats via ethtool gstats, try to
# get them from /proc/net/dev - tc
if [ "$rxpack" = "" ] || [ "$rxpack" = "N/A" ]
then
   printf "\n"
   get_basic_stats $iname
fi

printf "\n"
printf "\n"
}


# Get the Driver and PCI Related Info First

get_drv_info()
{
$ETHTOOL -i $iname > /tmp/$iname.iopt

drvname=`egrep ^driver /tmp/$iname.iopt | awk -F":" '{print $2}'|sed 's/^[ 	]*//g'`
drvversion=`egrep ^version /tmp/$iname.iopt | awk -F":" '{print $2}'|sed 's/^[ 	]*//g'`


bus_info=`grep bus-info /tmp/$iname.iopt`
slotinfo=`echo $bus_info | awk '{print $2}'`

if [ ${#bus_info} -le 17 ]
then
   # bus-info: 02:03.0
   busnum=`echo $bus_info | awk -F":" '{print $2}'| sed 's/^[ ]*0//g'`
   slotnum=`echo $bus_info | awk -F":" '{print $3}' | awk -F"." '{print $1}'| sed 's/^[         ]*0//g'`
   long_businfo=0
else
   # bus-info: 0000:02:03.0
   busnum=`echo $bus_info | awk -F":" '{print $3}'| sed 's/^[ ]*0//g'`
   slotnum=`echo $bus_info | awk -F":" '{print $4}' | awk -F"." '{print $1}'| sed 's/^[         ]*0//g'`

   # handle distros that return nothing when the domain is given to
   # lspci -s, even though the usage shows 
   # "[[[[<domain>]:]<bus>]:][<slot>][.[<func>]]"
   domain_test=`lspci -s $slotinfo 2>&1`
   if [ "$domain_test" = "" ]
   then
      # strip the domain from the bus-info
      slotinfo=`echo $slotinfo | awk -F":" '{printf "%s:%s",$2,$3}'`
      long_businfo=0
   else
      long_businfo=1
   fi
fi

busnum=`hex_to_int $busnum`
slotnum=`hex_to_int $slotnum`


get_speed_duplex_link

/bin/rm -rf /tmp/$iname.iopt
}

get_pci_info()
{

if [ ! -z "$bus_info" ]
then
	pcivendor=`lspci -s $slotinfo -n -m | awk '{print $4}' | sed 's/"//g'`
	pcidevice=`lspci -s $slotinfo -n -m | awk '{print $5}' | sed 's/"//g'`
	pcisubsys=`lspci -s $slotinfo -n -v | egrep -i subsystem | awk -F":" '{print $2}' | sed 's/"//g' | sed 's/^[ 	]*//g'`
	pcisubdev=`lspci -s $slotinfo -n -v | egrep -i subsystem | awk -F":" '{print $3}' | sed 's/"//g' | sed 's/^[ 	]*//g'`
	#00d0 = dual port Broadcom
	#00db = dual port Intel copper
	#00dc = dual port Intel fiber
	#3109 = PCI-X Quad Port Intel Copper
        #7044 = PCI Express Dual Port Intel Copper 
	if [ "$pcisubdev" = "00d0" -o "$pcisubdev" = "00db" -o "$pcisubdev" = "00dc" -o "$pcisubdev" = "3109" -o "$pcisubdev" = "7044" ]
	then
		getnexttoken=1
	 	#We have a multiport card here. Read both MAC addresses
	 	multiport=1
	fi
	pcirevid=`lspci  -n  -s $slotinfo | sed 's/[:()]//g' | awk '{print $6}'`
	descr=`lspci -s $slotinfo -v | grep "Subsystem" | awk -F":" '{print $2}'`
	irqstring=`lspci -s $slotinfo -n -v | egrep IRQ `
	getnexttoken=0
	for i in  `echo $irqstring`
	do
		if [ $getnexttoken = 1 ]
		then
	        	irq=$i
		break
		fi
		if [ $i = "IRQ" ]
		then
			getnexttoken=1
		fi
	done
	memory=`lspci -s $slotinfo -n -v | egrep -i "Memory at" | head -1 | awk '{print $3}' | sed 's/^[ 	]*//g'`
fi

caddr=`ifconfig $iname | grep HWaddr | awk  '{print $5}'`
phwaddr=
partno=

$ETHTOOL -e $iname offset 0 length 1 >/dev/null 2>&1
eeret=$?

if [ "$pcivendor" = "8086" ] && [ $eeret -eq 0 ]
then
	# We Have an Intel Card. Offset is 0x0
        get_part_no intel
       	# For Intel Cards, Permanent MAC Offset is 0x0
       	eeprom_offset="0x0"
       	bytes=6
        phwaddr=`$ETHTOOL -e $iname offset $eeprom_offset length $bytes | tail -1 | awk '{printf "%s:%s:%s:%s:%s:%s",$2,$3,$4,$5,$6,$7}'`
        func=`echo "$slotinfo" | awk -F"." '{print $2}'`
        if [ "$multiport" = "1" ] && [ "$func" = "1" ]
        then
          #this is the second port of a multiport intel gigabit NIC (NC7170)
          #so increment the MAC by 1
          phwaddr=`incr_mac "$phwaddr"`
        fi
	phwaddr=`echo $phwaddr | awk '{printf "%s", toupper($1)}'`
elif [ $eeret -eq 0 ]
then
        get_part_no broadcom
	if [ "$pcidevice" = "16aa" -o "$pcidevice" = "164a" -o "$pcidevice" = "16ac" -o "$pcidevice" = "164c" ]
	then
		# bcm5706, bcm5708
		eeprom_offset="0x136"
		bytes=6
		phwaddr=`$ETHTOOL -e $iname offset $eeprom_offset length $bytes | tail -1 | awk '{printf "%s:%s:%s:%s:%s:%s",$2,$3,$4,$5,$6,$7}'`
	else
		eeprom_offset="0x7c"
		bytes=8
		func=`echo "$slotinfo" | awk -F"." '{print $2}'`
		if [ "$multiport" == "1" ] && [ "$func" == "0" ]
		then
			eeprom_offset="0xcc"
		fi
		if [ "$drvname" = "tg3" ]
		then
			phwaddr=`$ETHTOOL -e $iname offset $eeprom_offset length $bytes | tail -6 | awk -Fx '{printf("%s:",$3)}' | sed 's/:$//g'`
		else
			phwaddr=`$ETHTOOL -e $iname offset $eeprom_offset length $bytes | tail -1 | awk '{printf "%s:%s:%s:%s:%s:%s",$4,$5,$6,$7,$8,$9}'`
		fi
	fi
        phwaddr=`echo $phwaddr | awk '{printf "%s", toupper($1)}'`
fi

if [ -z "$phwaddr" ] || [ "$phwaddr" = ":::::" ]
then
	phwaddr=`echo $caddr | awk '{printf "%s", toupper($1)}'`
fi
}

generate_statistics()
{

 einame=$1
 $ETHTOOL -S $einame > /tmp/$einame.stats 2>/dev/null

}
get_value()
{
 string1=$1
 string2=$2
 if [ -z "$string2" ];then
	 value=`egrep "^[ 	]*\$string1" /tmp/$iname.stats`
 else
	 value=`egrep "^[ 	]*\$string1|\$string2" /tmp/$iname.stats`
 fi
 value=${value## *:}
 echo ${value:-"N/A"}

}

get_speed_duplex_link()
{

$ETHTOOL $iname > /tmp/$iname.noopt

ifconfig $iname | grep UP > /dev/null 2>&1
if [ $? = 0 ]
then
   state=up
   links=`egrep "Link" /tmp/$iname.noopt`
   links=`echo ${links##*:} | sed 's/[ 	]*//g'`
   if [ "$links" = "yes" ]
   then
      link="Up"
      speedtmp=`egrep "Speed" /tmp/$iname.noopt`
      speedtmp=`echo ${speedtmp##*:} | sed 's/[ 	]*//g'`
      # Remove the Mb/s at the end of the string
      speed=${speedtmp/Mb\/s/}

      duplex=`egrep "Duplex" /tmp/$iname.noopt`
      duplex=`echo ${duplex##*:} | sed 's/[ 	]*//g'`

      echo $speed | egrep -i unknown > /dev/null 2>&1
      if [ $? = 0 ]
      then
         speed="N/A"
      fi
      echo $duplex | egrep -i unknown > /dev/null 2>&1
      if [ $? = 0 ]
      then
         duplex="N/A"
      fi
   else
      link="Down"
      speed="N/A"
      duplex="N/A"
   fi
else
   # if the interface is down, we can't trust that the driver will continue
   # to check the physical link status
   state=down
   link="N/A"
   speed="N/A"
   duplex="N/A"
fi

auto_negotiate="N/A"
auto_line=`grep "Advertised auto-negotiation:" /tmp/$iname.noopt 2>&1`

echo $auto_line | grep "Yes" >/dev/null
if [ $? = 0 ]
then
   auto_negotiate="on"
else
   echo $auto_line | grep "No" >/dev/null
   if [ $? = 0 ]
   then
      auto_negotiate="off"
   fi
fi

/bin/rm -rf /tmp/$iname.noopt

}

# Now we need to get the Statistics of the Appropriate interface
# Through the ethtool interface

get_stats()
{
generate_statistics $iname
if [ "$pcivendor" = "8086" ]
then
	rxpack=`get_value rx_packets`
	txpack=`get_value tx_packets`
	txbytes=`get_value tx_bytes`
	rxbytes=`get_value rx_bytes`
	txdrop=`get_value tx_dropped`
	rxdrop=`get_value rx_dropped`
	rxerrors=`get_value rx_errors`
	txerrors=`get_value tx_errors`
	multicast=`get_value multicast`
	collisions=`get_value collisions`
	rx_crc_errors=`get_value rx_crc_errors`
	tx_carrier_errors=`get_value tx_carrier_errors`
	rx_length_errors=`get_value rx_length_errors`
	rx_over_errors=`get_value rx_over_errors`
	rx_frame_errors=`get_value rx_frame_errors`
	rx_fifo_errors=`get_value rx_fifo_errors`
	tx_abort_excess_coll=N/A
	tx_abort_late_coll=`get_value tx_abort_late_coll`
	tx_deferred_ok=`get_value tx_deferred_ok`
	tx_single_coll_ok=`get_value tx_single_coll_ok`
	tx_multi_coll_ok=`get_value tx_multi_coll_ok`
	rx_short_length_errors=`get_value rx_length_errors`
	rx_long_length_errors=0
	rx_align_errors=`get_value rx_frame_errors`
else
	rxupack=`get_value rx_unicast_packets rx_ucast_packets`
	rxmpack=`get_value rx_multicast_packets rx_mcast_packets`
	rxbpack=`get_value rx_broadcast_packets rx_bcast_packets`
	rxpack=`expr $rxupack + $rxmpack + $rxbpack 2>/dev/null`
	txupack=`get_value tx_unicast_packets tx_ucast_packets`
	txmpack=`get_value tx_multicast_packets tx_mcast_packets`
	txbpack=`get_value tx_broadcast_packets tx_bcast_packets`
	txpack=`expr $txupack + $txmpack + $txbpack 2>/dev/null`
	txbytes=`get_value tx_bytes tx_octets`
	rxbytes=`get_value rx_bytes rx_octets`
	rxerrors=`get_value rx_errors`
	txerrors=`get_value tx_errors`
	rx_crc_errors=`get_value rx_crc_errors`
	tx_carrier_errors=`get_value tx_carrier_errors`
	tx_abort_excess_coll=`get_value tx_excess_collisions`
	tx_abort_late_coll=`get_value tx_late_collisions`
	rx_length_errors=`get_value rx_length_errors`
	rx_over_errors=`get_value rx_over_errors`
	rx_frame_errors=`get_value rx_frame_errors`
	rx_fifo_errors=`get_value rx_fifo_errors`
	tx_deferred_ok=`get_value tx_deferred`
	tx_single_coll_ok=`get_value tx_single_coll_ok`
	tx_multi_coll_ok=`get_value tx_multi_coll_ok`
	rx_short_length_errors=`get_value rx_short_length_errors`
	rx_long_length_errors=`get_value rx_long_length_errors`
	rx_align_errors=`get_value rx_align_errors`
fi
/bin/rm -rf /tmp/$iname.stats
}

get_part_no()
{
$ETHTOOL -e $iname offset 0 length 1 >/dev/null 2>&1
eeret=$?
if [ "$1" = "intel" ] && [ $eeret -eq 0 ]
then
   count=0
   partno=`$ETHTOOL -e $iname offset 16 length 4 | tail -1 | awk '{printf "%s%s%s-%s", $3,$2,$5,$4}'`
else # For Broadcom Cards partnumber is stored as hex. Convert to ASCII
   if [ "$pcidevice" = "164a" -o "$pcidevice" = "16aa" -o "$pcidevice" = "164c" -o "$pcidevice" = "16ac" ]
   then
      partnohex=`$ETHTOOL -e $iname offset 0x10c length 16 | tail -1 | cut -f3`
      partno=`echo "$partnohex" | perl -nle 'print join "", map { chr hex $_ } split " ";'`
   else
	if [ "$drvname" = "tg3" ]
	then
      		partnohex=`$ETHTOOL -e $iname offset 0x84 length 10 | tail | awk -Fx '{ printf("%s ",$3)}'`
      		partno=`echo "$partnohex" | perl -nle 'print join "", map { chr hex $_ } split " ";'`
	else

      		partnohex=`$ETHTOOL -e $iname offset 0x84 length 10 | tail -1 | cut -f3`
      		partno=`echo "$partnohex" | perl -nle 'print join "", map { chr hex $_ } split " ";'`
   	fi
   fi	
fi   

}

#========================================================
# 		Main Program Starts Here
#========================================================
TEMP=`/usr/bin/getopt 'i:f:d:A' "$@" 2>/dev/null`

if [ $? != 0 ] ; then
    usage
    exit 1
fi

eval set -- "$TEMP"
while true ; do
    case "$1" in
        -i) iname="$2" ; ioption=1 ; shift 2 ;;
        -f) fname="$2" ; foption=1 ; shift 2 ;;
        -d) dirname="$2" ; doption=1 ; shift 2 ;;
        -A) Aoption=1 ; shift ;;
         --) shift ; break ;;
         *) shift ; break ;;
    esac
done

# Perform sanity checks
check_for_errors
check_for_ethtool_ver

if [ "$foption" = "1" ]
then
  /bin/touch $fname >/dev/null 2>&1
  if [ "$?" != "0" ]
  then
    echo "Error!! Could not create $fname. Pl. check write permissions"
    exit 1
  else # Zero out the file contents if present
    > $fname
  fi
fi


# Generate Interface list if the user has given the -A option

if [ "$Aoption" = "1" ]
then
   interface_list=
   # Generate the ethX interface list
   for i in `ifconfig -a | egrep "^eth[0-9]*[0-9]" | awk '{print $1}' | egrep -v "[.:]"`
   do
      interface_list="$interface_list $i"
   done
   for i in `ifconfig -a | egrep "^vmnic[0-9]*[0-9]" | awk '{print $1}' | egrep -v "[.:]"`
   do
      interface_list="$interface_list $i"
   done
else
      # Check if this device exists on the system
      interface_list=$iname
      /sbin/ifconfig $iname > /dev/null 2>&1
      if [ $? != 0 ]
      then
           echo "Error!! $iname: Device does not exist. Exiting"
           exit 1
      fi
fi


# Now Dump the info either in the file for -f, directory
# For -d or stdout if none

for i in `echo $interface_list`
do
   iname=$i
   if [ "$doption" = "1" ]
   then
      fname=$dirname/$iname.info
      /bin/touch $fname > /dev/null 2>&1
      if [ "$?" != "0" ]
      then
        echo "Warning!! Could not create $fname. Pl. check write permissions"
        continue
      else # Zero out the file contents if present
        > $fname
      fi
   fi
   # If proc entries exist, use them
   if [ "$foption" = "1" -o "$doption" = "1" ]
   then
      # we cannot use copy here since -A with -f will overwrite.
      if [ -f $INTEL_PROC_DIR/$iname.info ]
      then
		cat $INTEL_PROC_DIR/$iname.info >> $fname
		echo -e "\n\n" >> $fname
		continue
      elif [ -f $BCOM_PROC_DIR/$iname.info ]
      then
		cat $BCOM_PROC_DIR/$iname.info >> $fname
		echo -e "\n\n" >> $fname
		continue
      elif [ -f $INTEL_VMWARE_PROC_DIR/$iname.info ]
      then
		cat $INTEL_VMWARE_PROC_DIR/$iname.info >> $fname
		echo -e "\n\n" >> $fname
		continue
      elif [ -f $BCOM_VMWARE_PROC_DIR/$iname.info ]
      then
		cat $BCOM_VMWARE_PROC_DIR/$iname.info >> $fname
		echo -e "\n\n" >> $fname
		continue
      fi
   else  # display to stdout
      if [ -f $INTEL_PROC_DIR/$iname.info ]
      then
		cat $INTEL_PROC_DIR/$iname.info
		continue
      elif [ -f $BCOM_PROC_DIR/$iname.info ]
      then
		cat $BCOM_PROC_DIR/$iname.info
		continue
      elif [ -f $INTEL_VMWARE_PROC_DIR/$iname.info ]
      then
		cat $INTEL_VMWARE_PROC_DIR/$iname.info
		continue
      elif [ -f $BCOM_VMWARE_PROC_DIR/$iname.info ]
      then
		cat $BCOM_VMWARE_PROC_DIR/$iname.info
		continue
      fi
   fi
   # 
   # Note that always the get_drv_info
   # needs to be called first
   #
   if [ "$doption" = "1" ]
   then
	staticfname=$dirname/.$iname.sinfo
        if [ ! -f "$staticfname" ]
	then
   		get_drv_info 
   		get_pci_info
	else
		# We still need pcivendor to determine
		# Which card this is.
		pcivendor=`grep -i pci_vendor $staticfname|awk '{print $2}' | sed 's/0x//g'`
	fi
   else
   		get_drv_info 
   		get_pci_info
   fi
   get_speed_duplex_link
   get_stats
   #
   # Re-direct output appropriately
   #
   if [ "$doption" = "1" ]
   then
        if [ -f "$staticfname" ]
	then
          cp $staticfname $fname
          display_dynamic_proc >> $fname 2>&1
	else
          display_static_proc > $staticfname 2>&1
          cp $staticfname $fname
          display_dynamic_proc >> $fname 2>&1
	fi
   elif [ "$foption" = "1" ]
   then
      display_static_proc >> $fname 2>&1
      display_dynamic_proc >> $fname 2>&1
   else
      display_static_proc
      display_dynamic_proc
   fi
done
