The Moose and Squirrel Files

September 24, 2008

Re-Imaging Computers in 802.1x Networks – Part 5

Filed under: Code, Network — Tags: , , , , — networknerd @ 8:24 pm

This is the final post in this series on re-imaging in 802.1x networks. It ties all the other posts together and contains the complete altiris re-imaging script in one listing.  Although I haven’t covered it here, a post-image script is also required to set the switch port back to using dot1x after the image is dropped from the computer and joined to the domain to get it’s authentication credentials.

Altiris scripting
The observant reader would have noticed that additional information is required before we can perform the previous five steps in a script. The mac address of the computer, the re-imaging vlan and the management IP address of the switch are also required. Variables are provided by altiris which help obtain the additional information. The mac address is provided straight up as %NIC1MACADDR%. The management IP address of the switch and re-imaging vlan aren’t directly available. Altiris has no knowledge of these items. However networks built to a standard allow calculation of the remaining two parameters. The computers ip address provided in the %NIC1IPADDR% variable is used for this calculation. The example network was built to the design standard below.

  • Floor vlans will be allocated in the range 100 – 299 with 10 vlans being reserved per floor.
  • Floor ip addresses will be allocated in the range 192.168.32.0 – 192.168.191.255 with 8 class C networks reserved per floor.
  • The first three networks and vlans per floor will be allocated to authenticated computers, guest/auth-fail computers and re-imaging vlan respectively.
  • The fourth network and vlan will be reserved for future IP telephony projects.
  • The fifth network will be allocated to switch management IP addresses with all others reserved for future use.
  • Switch management vlans will be allocated in the range 300 – 350.
  • Edge switch management address will start at 192.168.x.11

The ip address of the first network on a floor is calculated by masking the last three bits in the third octet of the computers ip address (%NIC1IPADDR%). The fifth network on each floor is reserved for switch management. Adding 4 to the third octet gives the switch management network. Assuming the last octet of the switch management IP addresses are also kept consistent, the address can be completed by simply changing the fourth octet to the standard value. Refer to the getSwitchMgmtAddr() function in listing 1.

The vlan of the first network on a floor is calculated using a similar technique. The vlan in which the computers mac address was found is divided, using integer division, by the number of vlans per floor. The result is then multiplied by the number of vlans per floor. The third network and vlan are reserved for re-imaging. Adding 2 to the first vlan on the floor will give the re-imaging vlan.

As an example, assume that the computer to be re-imaged has an ip address of 192.168.42.157 and its mac address was found in vlan 112 (probably due to a failed re-image job). Masking the last three bits of the third octet gives the first network on the floor.
00101010 (42)
AND 11111000 (248)
= 00101000 (40)
The management network is found by adding 4 to the third octet and gives 192.168.44.0/24, and the switch management ip address will be 192.168.44.11. The first vlan on a floor is calculated as (112\10) * 10 = 110. The re-imaging vlan is found by adding 2 to give 112. Note that the use of integer division- denoted by \ rather than / – means that remainders are ignored.

Not every network is the way we would design it with hindsight. Networks often grow in odd ways. You may have inherited a flat network that won’t lend itself to this kind of calculation. In this case you can simply build an array of switch management ip addresses and loop through steps one and two for each switch until the bridgeport on which the mac address appears is found on a non-trunking port. Then continue with steps three to five.

The script in listing 1 should be easy to customise for your environment. Pay particular attention to the constants defined at the beginning, the regular expression patterns used to match the output from the snmp commands, and the snmp commands. If you aren’t familiar with regular expressions take a look at “Mastering Regular expressions” by Jeffrey Friedl.

With snmp and a modicum of scripting know-how you can now have dot1x security without fearing an uprising of angry helpdesk staff.

References

How To Add, Modify, and Remove VLANs on a Catalyst Using SNMP. (October 26, 2005).
     Retrieved 11 November, 2006, from
     http://www.cisco.com/en/US/tech/tk648/tk362/technologies_tech_note09186a00801c6035.shtml

Using SNMP to Find a Port Number from a MAC Address on a Catalyst Switch. (October 26, 2005).
     Retrieved 11 November, 2006, from
     http://www.cisco.com/en/US/tech/tk648/tk362/technologies_tech_note09186a00801c9199.shtml

How To Get Dynamic CAM Entries (CAM Table) for Catalyst Switches Using SNMP. (October 26, 2005).
     Retrieved 11 November, 2006, from
     http://www.cisco.com/en/US/tech/tk648/tk362/technologies_tech_note09186a0080094a9b.shtml

How to Get VLAN Information From a Catalyst Using SNMP. (October 26, 2005).
     Retrieved 11 November, 2006, from
     http://www.cisco.com/en/US/tech/tk648/tk362/technologies_configuration_example09186a008015773e.shtml

SNMP Community String Indexing. (October 26, 2005).
     Retrieved 11 November, 2006, from
     http://www.cisco.com/en/US/tech/tk648/tk362/technologies_tech_note09186a00801576ff.shtml

IEEE Standard for Local and metropolitan area networks—Port-Based Network Access Control. (2004).
     Retrieved 11 November, 2006, from
     http://standards.ieee.org/getieee802/download/802.1X-2004.pdf

Friedl, J. (2002). Mastering Regular Expressions (Second ed.): O'Reilly Media Inc.

Listing 1


option explicit
const REIMAGE_VLAN_OFFSET = 2
const VLAN_FLOOR_INCREMENT = 20
const SW_MGMT_LAST_OCTET = 11
const FORCEUNAUTHORISED = 1
const AUTO = 2
const FORCEAUTHORISED = 3
const VMVLAN = ".1.3.6.1.4.1.9.9.68.1.2.2.1.2."
const dot1xAuthAuthControlledPortControl = ".1.0.8802.1.1.1.1.2.1.1.6."
const VTPVLANSTATE = " .1.3.6.1.4.1.9.9.46.1.3.1.1.2 "
const DOT1DTPFDBPORT = " .1.3.6.1.2.1.17.4.3.1.2"
const DOT1DBASEPORTIFINDEX = " .1.3.6.1.2.1.17.1.4.1.2."
const vlanPortIslVlansAllowed = " .1.3.6.1.4.1.9.5.1.9.3.1.5.1.1 "
const SNMPGETCMD2 = "f:\usr\bin\snmpget.exe -Ov -v 2c -c "
const SNMPWALKCMD = "f:\usr\bin\snmpwalk.exe -OnqUe -v 2c -c "
const SNMPSETCMD = "f:\usr\bin\snmpset.exe -v 2c -c "
const SNMPGETCMD = "f:\usr\bin\snmpget.exe -OnqUe -v 2c -c "
const SNMPWRITE = " private "
const SNMPREAD = " public "
const SNMPREADV = " public@" 'need community name and vlan for some info
const SHUTDOWNCMD = "c:\windows\system32\shutdown.exe -m "
const SHUTDOWNARGS = " -r -f -t 1"

dim arrVlans, vlan
dim bridgeport, ifindex
dim strMgmtIP, strMACAddress, WshShell, intresult, strAgntAddr

Set WshShell = CreateObject("WScript.Shell")

'************************************************************************
'  get the switch management IP address                                 *
'         Altiris provides us with the mac address                      *
'************************************************************************
if "%NIC1IPADDR%" = "0.0.0.0" then
  strMgmtIP = getSwitchMgmtAddr("%NIC2IPADDR%")
  strMACAddress = lcase("%NIC2MACADDR%")
  strAgntAddr = "%NIC2IPADDR%"
Else
  strMgmtIP = getSwitchMgmtAddr("%NIC1IPADDR%")
  strMACAddress = lcase("%NIC1MACADDR%")
  strAgntAddr = "%NIC1IPADDR%"
end if

'************************************************************************
' Step one - get the list of vlans                                      *
'************************************************************************
arrVlans = enum_AllowedVLAN(strMgmtIP)

'************************************************************************
' Step two - get the bridgeport                                         *
'************************************************************************
for each vlan in arrVlans
  bridgeport = getBridgePort(strMgmtIP, vlan, strMACAddress)
  if bridgeport <> "" then
    exit for
  end if
next
if bridgeport = "" then
  wshShell.logevent 1,"Bridgeport not found for mac address "  & _
        strMACAddress & " For Computer %NAME%"
  wscript.quit
end if

'************************************************************************
' Step three - get the interface index                                  *
'************************************************************************
ifindex = getIFIndex(strMgmtIP, vlan, bridgeport)
if ifindex = "" then
  wshShell.logevent 1,"ifindex not found for mac address "  & _
        strMACAddress & " For Computer %NAME%"
  wscript.quit
end if

'************************************************************************
' Step four - set the dot1x port control                                *
'************************************************************************
intresult = setPortControl(strMgmtIP,ifindex, FORCEAUTHORISED)

'************************************************************************
' reboot the computer so that it picks up a new dhcp address            *
'        in the re-imaging vlan.                                        *
'************************************************************************
RebootComputer("\\" & strAgntAddr)

'************************************************************************
' Step five - set the vlan to our re-imaging vlan                       *
' note the use of integer division operator \                           *
'************************************************************************
vlan = (vlan \ VLAN_FLOOR_INCREMENT ) * VLAN_FLOOR_INCREMENT _
         + REIMAGE_VLAN_OFFSET
intresult = intresult + setVlan(strMgmtIP,ifindex, vlan)
if intresult = 0 then
  wshShell.logevent 4, "Reimage vlan " & Vlan & " for %NAME%," & _
        StrMgmtIP & "," & ifindex
Else
  wshShell.logevent 1, "Port " & ifindex & " on " & StrMgmtIP & _
        " for %NAME% was Not set correctly"
End If
wscript.quit

'************************************************************************
'FUNCTION:                                                              *
'       setVlan(strAgent,intIFIndex, intVlan)                           *
'                                                                       *
'Purpose:                                                               *
'       set the port specified by the interface index suitable to       *
'       the specified vlan                                              *
'                                                                       *
'Inputs:                                                                *
'       strAgent: management IP address of the switch                   *
'       intIFIndex: port interface index returned from getIFIndex()     *
'       intVlan : the vlan to which the port should be configured       *
'                                                                       *
'Returns:                                                               *
'       Integer, 0 if successful or a positive value on failure.        *
'                                                                       *
'Calls:                                                                 *
'       SNMPSETCMD - constant defining the path to an external          *
'       program and options used to perform an snmp set                 *
'                                                                       *
'Comments:                                                              *
'       CISCO-VTP-MIB is cisco specific.                                *
'       Reference cisco Document ID: 45080                              *
'       "How To Add, Modify, and Remove VLANs on a Catalyst Using SNMP" *
'       viewed at                                                       *
'       http://www.cisco.com/en/US/tech/tk648/tk362/                    *
'                technologies_tech_note09186a00801c6035.shtml           *
'       on 16/11/2006                                                   *
'************************************************************************
function  setVlan(strAgent,intIFIndex, intVlan)
dim WshShell, oExec
dim stroutput

  Set WshShell = CreateObject("WScript.Shell")
  Set oExec = WshShell.Exec(SNMPSETCMD & SNMPWRITE & " " & strAgent & _
                " " & VMVLAN & intIFIndex & " i " & intVlan)
  Do while Not oExec.StdOut.AtEndOfStream
    stroutput = oExec.StdOut.readall
  Loop
  Do While oExec.Status <> 1
    WScript.Sleep 100
  Loop
  setVlan = instr(1, stroutput, "Error")
end function

'************************************************************************
'FUNCTION:                                                              *
'       setPortControl(strAgent,intIFIndex, intPortControl)             *
'                                                                       *
'Purpose:                                                               *
'       sets the PaeControlledPortControl value which controls whether  *
'       dot1x authentication is required.                               *
'                                                                       *
'Inputs:                                                                *
'       strAgent: management IP address of the switch                   *
'       intIFIndex: port interface index returned from getIFIndex()     *
'       intPortControl : the control values of the authenticator PAE    *
'               controlled port. Allowed values are                     *
'               forceUnauthorized(1), auto(2),forceAuthorized(3)        *
'                                                                       *
'Returns:                                                               *
'       Integer, 0 if successful or a positive value on failure.        *
'                                                                       *
'Calls:                                                                 *
'       SNMPSETCMD - constant defining the path to an external          *
'       program and options used to perform an snmp set                 *
'                                                                       *
'Comments:                                                              *
'       Reference IEEE Std 802.1X-2001                                  *
'       "IEEE Standard for Local and metropolitan area networks—        *
'               Port-Based Network Access Control"                      *
'       viewed at                                                       *
'       http://standards.ieee.org/getieee802/download/802.1X-2001.pdf   *
'       on 16/11/2006                                                   *
'************************************************************************
function  setPortControl(strAgent,intIFIndex, intPortControl)
dim WshShell, oExec
dim stroutput

  if (intPortControl < FORCEUNAUTHORISED or _
                intPortControl > FORCEAUTHORISED) then
    setPortControl = 1
    exit function
  end if
  Set WshShell = CreateObject("WScript.Shell")
  Set oExec = WshShell.Exec(SNMPSETCMD & SNMPWRITE & " " & strAgent & _
                " " & dot1xAuthAuthControlledPortControl & intIFIndex &_
                " i " & intPortControl)
  Do while Not oExec.StdOut.AtEndOfStream
    stroutput = oExec.StdOut.readall
  Loop
  Do While oExec.Status <> 1
    WScript.Sleep 100
  Loop
  setPortControl = instr(1, stroutput, "Error")
end function

'************************************************************************
'FUNCTION:                                                              *
'       getIFIndex(strAgent, intVlan, intBridgePort)                    *
'                                                                       *
'Purpose:                                                               *
'       convert a bridgeport value to an interface index suitable for   *
'       use with the setvlan() and setportcontrol() functions           *
'                                                                       *
'Inputs:                                                                *
'       strAgent: management IP address of the switch                   *
'       intVlan : the vlan specific instance of the forwarding table    *
'       intBridgePort: bridgeport value returned from getBridgePort()   *
'                                                                       *
'Returns:                                                               *
'       String containing the interface index, or an empty string on    *
'       failure                                                         *
'                                                                       *
'Calls:                                                                 *
'       SNMPGETCMD - constant defining the path to an external          *
'       program and options used to perform an snmp get                 *
'                                                                       *
'Comments:                                                              *
'       Uses community string indexing to reference the per vlan mib    *
'       instance.                                                       *
'       Reference cisco Document ID: 44800                              *
'       "Using SNMP to Find a Port Number from a MAC Address on a       *
'       Catalyst Switch" viewed        at                               *
'       http://www.cisco.com/en/US/tech/tk648/tk362/                    *
'               technologies_tech_note09186a00801c9199.shtml            *
'       on 16/11/2006                                                   *
'************************************************************************
function getIFIndex(strAgent, intVlan, intBridgePort)
dim WshShell, oExec
dim re 'as regexp
dim matches
dim match
dim tempstr, stroutput

  Set WshShell = CreateObject("WScript.Shell")
  Set oExec = WshShell.Exec(SNMPGETCMD & SNMPREADV & intVlan & " " & _
                strAgent & " " & DOT1DBASEPORTIFINDEX & intBridgePort)
  Do while Not oExec.StdOut.AtEndOfStream
    stroutput = oExec.StdOut.readall
  Loop
  Do While oExec.Status <> 1
    WScript.Sleep 100
  Loop

  set re = new regexp
  re.global = True
  re.multiline = True
'Pattern to capture the last digits of the snmp output
'output lines from SNMPCMD should look like
'                ".1.3.6.1.2.1.17.1.4.1.2.108 11002"
  re.pattern = "^" & trim(DOT1DBASEPORTIFINDEX) & intBridgePort & _
                "\s+(\d+)$"

  tempstr = ""
  set matches = re.execute(stroutput)
  for each match in matches
    tempstr = match.submatches(0)
  next
  getIFIndex = tempstr
end function

'************************************************************************
'FUNCTION:                                                              *
'       getBridgePort(strAgent, intVlan, strmac)                        *
'                                                                       *
'Purpose:                                                               *
'       examine the switch forwarding tables for the specified mac      *
'       address in the specified vlan                                   *
'                                                                       *
'Inputs:                                                                *
'       strAgent: management IP address of the switch                   *
'       intVlan : the vlan specific instance of the forwarding table    *
'       strmac  : Mac address string in the format 0040CA6934EE         *
'                                                                       *
'Returns:                                                               *
'       String containing the bridgeport if found or an empty string    *
'                                                                       *
'Calls:                                                                 *
'       SNMPGETCMD - constant defining the path to an external          *
'       program and options used to perform an snmp get                 *
'                                                                       *
'Comments:                                                              *
'       Uses community string indexing to reference the per vlan mib    *
'       instance.                                                       *
'       Reference cisco Document ID: 44800                              *
'       "Using SNMP to Find a Port Number from a MAC Address on a       *
'       Catalyst Switch" viewed        at                               *
'       http://www.cisco.com/en/US/tech/tk648/tk362/                    *
'               technologies_tech_note09186a00801c9199.shtml            *
'       on 16/11/2006                                                   *
'************************************************************************
function getBridgePort(strAgent, intVlan, strmac)
dim WshShell, oExec
dim re 'as regexp
dim matches
dim match
dim tempstr, stroutput

  Set WshShell = CreateObject("WScript.Shell")
  Set oExec = WshShell.Exec(SNMPGETCMD & SNMPREADV & intVlan & " " & _
        strAgent & " " & DOT1DTPFDBPORT & mac2oid(strmac))
  Do while Not oExec.StdOut.AtEndOfStream
    stroutput = oExec.StdOut.readall
  Loop
  Do While oExec.Status <> 1
    WScript.Sleep 100
  Loop
 set re = new regexp
  re.global = True
  re.multiline = True
'output lines from SNMPCMD should look like
'        ".1.3.6.1.2.1.17.4.3.1.2.0.64.202.105.52.238 108"
'Pattern to capture the snmpget output
  re.pattern = "^" & trim(DOT1DTPFDBPORT) & mac2oid(strmac) & "\s+(\d+)$"

  tempstr = ""
  set matches = re.execute(stroutput)
  for each match in matches
    tempstr = match.submatches(0)
  next
  getBridgePort = tempstr
end function

'************************************************************************
'FUNCTION:                                                              *
'       enum_AllowedVLAN(strAgent)                                      *
'Purpose:                                                               *
'       enumerate the vlans configured on the switch.                   *
'                                                                       *
'Inputs:                                                                *
'       strAgent: management IP address of the switch                   *
'                                                                       *
'Returns:                                                               *
'       Array with each element containing a vlan number                *
'                                                                       *
'Calls:                                                                 *
'       SNMPGETCMD2 - constant defining the path to an external         *
'       program and options used to perform an snmp get operation.      *
'       fmtBinary - function to left pad a binary number with zeros     *
'       ToBinary - function to convert an integer to a binary string    *
'                                                                       *
'Comments:                                                              *
'       CISCO-STACK-MIB  is cisco specific.                             *
'       Reference Cisco SNMP Object Navigator viewed at                 *
'       http://tools.cisco.com/Support/SNMP/do/BrowseOID.do?            *
'              objectInput=vlanPortIslVlansAllowed&translate=Translate& *
'              submitValue=SUBMIT&submitClicked=true                    *
'       on 16/11/2006                                                   *
'************************************************************************
function enum_AllowedVLAN(strAgent)
dim WshShell, oExec
dim re 'as regexp
dim matches
dim match, submatch
dim tempstr, stroutput, index, vlans

  Set WshShell = CreateObject("WScript.Shell")
  Set oExec = WshShell.Exec(SNMPGETCMD2 & SNMPREAD & " " & _
                strAgent & " " & vlanPortIslVlansAllowed)
  Do while Not oExec.StdOut.AtEndOfStream
    stroutput = oExec.StdOut.readall
  Loop
  Do While oExec.Status <> 1
    WScript.Sleep 100
  Loop
  tempstr = ""

  set re = new regexp
  re.global = True
  re.multiline = True
'Pattern to capture the hex digits representing the allowed vlans.
  re.pattern = "[0-9a-fA-F]{2}"

  vlans = ""
  if instr(1,stroutput, "Hex-STRING:") > 0  then
    set matches = re.execute(stroutput)
    for each match in matches
      tempstr =  tempstr & fmtBinary(ToBinary(cint("&H" & match)), 8)
      next
    tempstr = strreverse(tempstr)
    index = 1
    do
      index = instr(index, tempstr, "1")
      if index <> 0 then
        vlans = vlans & " " & index - 1
        index = index + 1
      end if
    loop until index = 0
  end if
  enum_AllowedVLAN = split(trim(vlans))
end function

'************************************************************************
'FUNCTION:                                                              *
'       fmtBinary(strNumber, intLength)                                 *
'PURPOSE:                                                               *
'       function to left pad a binary number with zeros                 *
'                                                                       *
'INPUTS:                                                                *
'       strNumber: binary number to left pad with zeros                 *
'       intLength: The desired bit length of the binary number          *
'                                                                       *
'RETURNS:                                                               *
'       string containing the binary representation of the input.       *
'                                                                       *
'CALLS:                                                                 *
'       Nothing                                                         *
'                                                                       *
'COMMENTS:                                                              *
'************************************************************************
function fmtBinary(strNumber, intLength)
  fmtBinary = string(intLength - len(strNumber), "0") & strNumber
end function

'************************************************************************
'FUNCTION:                                                              *
'       ToBinary(intNumber)                                             *
'                                                                       *
'PURPOSE:                                                               *
'       convert an integer number to binary.                            *
'                                                                       *
'Inputs:                                                                *
'       intNumber: Number to convert to binary                          *
'                                                                       *
'Returns:                                                               *
'       string containing the binary representation of the input.       *
'                                                                       *
'Calls:                                                                 *
'       Nothing                                                         *
'                                                                       *
'Comments:                                                              *
'       note the use of \ (integer division operator) rather than /     *
'************************************************************************
function ToBinary(intNumber)
  if intNumber > 0 then
    ToBinary = ToBinary(intNumber\2) & intNumber mod 2
  end if
end function

'************************************************************************
'FUNCTION:                                                              *
'       enum_VLAN(strAgent)                                             *
'Purpose:                                                               *
'       enumerate the vlans configured on the switch.                   *
'                                                                       *
'Inputs:                                                                *
'       strAgent: management IP address of the switch                   *
'                                                                       *
'Returns:                                                               *
'       Array with each element containing a vlan number                *
'                                                                       *
'Calls:                                                                 *
'       SNMPWALKCMD - constant defining the path to an external         *
'       program used to perform an snmp walk                            *
'                                                                       *
'Comments:                                                              *
'       CISCO-VTP-MIB is cisco specific.                                *
'       Reference cisco Document ID: 41003                              *
'       "How to Get VLAN Information From a Catalyst Using SNMP" viewed *
'       at http://www.cisco.com/en/US/tech/tk648/tk362/technologies_    *
'                configuration_example09186a008015773e.shtml            *
'        on 16/11/2006                                                  *
'************************************************************************
function enum_VLAN(strAgent)
dim WshShell, oExec
dim re 'as regexp
dim matches
dim match
dim tempstr, stroutput

  set re = new regexp
  re.global = True
  re.multiline = True
'output lines from SNMPCMD should look like
'        ".1.3.6.1.4.1.9.9.46.1.3.1.1.2.1.125 1"
'Pattern to capture the last digits of the snmp OID
'Include VTPVLANSTATE in the pattern to minimise regex engine backtracking
  re.pattern = "^" & VTPVLANSTATE & "(?:\.\d+)+\.(\d+)\s+\d+$"

  Set WshShell = CreateObject("WScript.Shell")
  Set oExec = WshShell.Exec(SNMPWALKCMD & SNMPREAD & " " & strAgent & " " & VTPVLANSTATE)
  Do while Not oExec.StdOut.AtEndOfStream
    stroutput = oExec.StdOut.readall
  Loop
  Do While oExec.Status <> 1
    WScript.Sleep 100
  Loop
  tempstr = ""
  set matches = re.execute(stroutput)
  for each match in matches
    tempstr = tempstr & match.submatches(0) & " "
  next
  enum_VLAN = split(trim(tempstr))
end function

'************************************************************************
'FUNCTION:                                                              *
'       mac2OID(strmac)                                                 *
'Purpose:                                                               *
'       Convert mac address string to a decimal string for snmp queries.*
'                                                                       *
'Inputs:                                                                *
'       strmac: Mac address string in the format 0040CA6934EE           *
'                                                                       *
'Returns:                                                               *
'       snmp OID string of the form .0.64.202.105.52.238 or an empty    *
'        string ("") if an error occured.                               *
'                                                                       *
'Calls:                                                                 *
'       Hex2Dec                                                         *
'                                                                       *
'Comments:                                                              *
'        No error checking is performed on the input character set.     *
'        The input string is validated by length only.                  *
'************************************************************************
function mac2OID(strmac)
dim intOctet
dim arrOctet
dim strOID

  strOID = ""
  if len(strmac) = 12 then
    for intOctet = 1 to 11 step 2
      strOID = strOID & "." & Hex2Dec(mid(strmac,intOctet,2))
    next
  end if
  mac2OID = strOID
end function

'************************************************************************
'FUNCTION:                                                              *
'       Hex2Dec(strHex)                                                 *
'Purpose:                                                               *
'       Convert a string representation of a hexadecimal number to a    *
'       decimal string.                                                 *
'                                                                       *
'Inputs:                                                                *
'       strHex: string containing hexadecimal characters [0-9a-fA-F]    *
'                                                                       *
'Returns:                                                               *
'       string containing the input converted to decimal characters[0-9]*
'                                                                       *
'Calls:                                                                 *
'       Nothing                                                         *
'                                                                       *
'Comments:                                                              *
'       No error checking is performed on the input.                    *
'       Beware of overflow in CInt function. Consider modifying to Clng *
'       before using in other code.                                     *
'************************************************************************
Function Hex2Dec(strHex)
Hex2Dec = "" & CInt("&H" & strHex)
End Function

'************************************************************************
'FUNCTION:                                                              *
'       getSwitchMgmtAddr(clientIPAddr)                                 *
'Purpose:                                                               *
'       Determine the switch management IP address from the client IP   *
'       address.                                                        *
'                                                                       *
'Inputs:                                                                *
'       clientIPAddr: string the client IP address in dotted notation   *
'                                                                       *
'Returns:                                                               *
'       string containing the switch management IP address in dotted    *
'       notation.                                                       *
'                                                                       *
'Calls:                                                                 *
'       Nothing                                                         *
'                                                                       *
'Comments:                                                              *
'       No error checking is performed on the input.                    *
'************************************************************************
Function getSwitchMgmtAddr(clientIPAddr)
dim intOctet
dim arrOctet

  arrOctet = split(clientIPAddr, ".")
  intOctet = arrOctet(2) and &HF8
  arrOctet(2) = intOctet + 4
  arroctet(3) = SW_MGMT_LAST_OCTET
  getSwitchMgmtAddr = join(arrOctet, ".")
end Function

'************************************************************************
'SUBROUTINE:                                                            *
'       RebootComputer(AgentName)                                       *
'Purpose:                                                               *
'       Perform a remote reboot of the specified computer               *
'                                                                       *
'Inputs:                                                                *
'       AgentName: string containing the host to reboot as hostname or  *
'       ip address preceded by two backslashes ie \\192.168.32.100      *
'                                                                       *
'Returns:                                                               *
'       Nothing                                                         *
'                                                                       *
'Calls:                                                                 *
'       external OS utility c:\windows\system32\shutdown.exe            *
'                                                                       *
'Comments:                                                              *
'       No error checking is performed on the input.                    *
'************************************************************************
sub RebootComputer(AgentName)
dim WshShell, oExec
dim stroutput

  Set WshShell = CreateObject("WScript.Shell")
  Set oExec = WshShell.Exec(SHUTDOWNCMD & AgentName & SHUTDOWNARGS)
  Do while Not oExec.StdOut.AtEndOfStream
    stroutput = oExec.StdOut.readall
  Loop
  Do while Not oExec.Stderr.AtEndOfStream
    stroutput = stroutput & oExec.Stderr.readall
  Loop
  Do While oExec.Status <> 1
    WScript.Sleep 100
  Loop
  if len(stroutput) <> 0 then
    wshShell.logevent 1, AgentName & _
        " did not accept the reboot request" & VBCRLF & stroutput
  end if
end sub

Advertisements

Leave a Comment »

No comments yet.

RSS feed for comments on this post. TrackBack URI

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Blog at WordPress.com.

%d bloggers like this: