How to extend Net-SNMP to retrieve system specification / hardware specifications from system_profiler under OS X

System Requirements:

  • OS X 10.2+
  • Net-SNMP

The Problem:

The thing that I have never understood with SNMP is why others, particularly OEM’s do not see it as a extremely useful and worth while (if badly implemented) technology.

If you have ever attempted to lookup system information on Windows, you will probably have used WBEM; it is eloquent, effective and Microsoft do a great job of keeping it fresh and current. While WBEM is available as OpenWBEM for Unix/Linux, it seems more like something designed to ward small children from a path along the dark side than anything usable by system administrators.

Unfortunately while WBEM on Windows is well maintained by Microsoft, the same is not said of SNMP. While WBEM has been enriched with access to new vectors on system analysis, most implementations of SNMP are nothing more than the most basic set of target variables available through a default Net-SNMP install – in short very little of any real use.

Cue Apple to make a bad situation worse – in a way only they know how.

OS X 10.6

Enabling SNMP on OS X 10.6, I noticed a fairly glaring problem

.1.3.6.1.2.1.2.2.1.6.4 = STRING: 00:93:e9:05:1c:67
.1.3.6.1.2.1.2.2.1.6.5 = STRING: 00:93:e9:05:1c:67

SNMP was returning the same MAC address for two separate adapters. What that should have said was:

.1.3.6.1.2.1.2.2.1.6.4 = STRING: 10:93:e9:05:1c:67
.1.3.6.1.2.1.2.2.1.6.5 = STRING: 02:93:e9:05:1c:67

Notice that the first hex pair in the actual output has been 00’d.

  1. So I remade the SNMP configuration files
  2. Reset the services
  3. Fully patched OS X 10.6 up to 10.6.8

No change! So off we go to the App store and buy 10.7…

OS X 10.7

After the install, same problem.

So I fully patched it up to 10.7.4… same problem.

Then I noticed something else…

Under 10.6.8 “system memory size in bytes” or in the vernacular of SNMP .1.3.6.1.2.1.25.2.2 or iso.identified-organization.dod.internet.mgmt.mib-2.host.hrStorage.hrMemorySize was returning “INTEGER: 2147483648”. Under 10.7.0 and 10.7.4 it now returned “”.

Yep, nothing, nada, zip.

So not only paying out for the OS upgrade failed to fix the problem, but it has made things worse!

In Summary

If you are determined to use SNMP to obtain system information on a Mac, what can you do given that Apple have crippled it? Read-on.

More Info

Here is an up front disclaimer for you

  1. This is not ideal
  2. It does not follow in the spirit for which SNMP was designed
  3. It does work
  4. I’ve only validated it under 10.7 but in theory it should work down to at least 10.2

The Fix

Net-SNMP (the SNMP service that ships with OS X) can of course be extended with Management Information Base (MIB) extensions to formally restore this missing functionality. You as a diligent systems administrator can of course write your own because Apple clearly don’t want to provide any.

It is however quite time consuming to write your own MIB and integrate it into SNMP. So what I propose is using the SNMP Enterprise Extension MIB’s to retrieve the information that you require on the local host and make it available through the snmp daemon.

To make use of the Enterprise Extensions:

  1. Open your preferred shell (Terminal)
  2. cd /private/etc/snmp
  3. sudo emacs OSX_Inventory.sh
  4. Provide your password and then type out the following (pay attention to where I have spaces, they are important):
    arg=$1
    if [[ “$arg” == “SerialNumber” ]]; then
    /usr/sbin/system_profiler SPHardwareDataType | grep “Serial Number” | cut -d”:” -f2- | cut -d” ” -f2-
    elif [[ “$arg” == “ModelNumber” ]]; then
    /usr/sbin/system_profiler SPHardwareDataType | grep “Model Identifier” | cut -d”:” -f2- | cut -d” ” -f2-
    fi
  5. Save the file (Ctrl + X, Ctrl + S) and then exit (Ctrl + X, Ctrl + C)
  6. Configure SNMP as you require:
    snmpconf -g basic_setup
  7. cd /private/etc/snmp (if you left the directory)
  8. sudo emacs snmpd.conf
  9. Provide your password if asked
  10. Scroll down until you get to the “Executables/scripts” section. Beneath “exec echotest /bin/echo hello world” add:
    exec info_SerialNumber       /bin/sh /private/etc/snmp/OSX_Inventory.sh SerialNumber
    exec info_ModelNumber       /bin/sh /private/etc/snmp/OSX_Inventory.sh ModelNumber
  11. Save the file (Ctrl + X, Ctrl + S) and then exit (Ctrl + X, Ctrl + C)
  12. Stop the SNMPd service:
    sudo killall snmpd
  13. Restart it (OS X will do this for you if you have set it to auto-start):
    snmpd
  14. Now issue a SNMPTable command against the User account / community string you specified in SNMP setup against this OID: .1.3.6.1.4.1.2021.8 e.g.
    snmptable -v 1 -c private localhost .1.3.6.1.4.1.2021.8

If you did everything correctly you should see something along the lines of:

extIndex extNames extCommand extResult extOutput extErrFix extErrFixCmd
INTEGER: 1 STRING: info_SerialNumber STRING: /bin/sh INTEGER: 0 STRING: <YOUR SERIAL NUMBER HERE>
INTEGER: 2 STRING: info_ModelNumber STRING: /bin/sh INTEGER: 0 STRING: MacBookAir3,2

If you extend the OSX_Inventory.sh script with additional field definitions and add them to the SNMPd.conf, you can retrieve any information you want from SNMP using SNMPGet, SMNPTable or SNMPWalk against the descendants of .1.3.6.1.4.1.2021.8.

Things to keep in mind:

  1. You can only return one (1) line via the Enterprise extensions section, anything after the first LF is dropped. If you need to return multiple lines, I suggest storing all lines in a variable in OSX_Inventory.sh and using tab separation by replacing LF (\n) with TAB (\t).
  2. Enterprise management and monitoring systems will not know about these extensions, clearly they are proprietary to you.
  3. You will need to distribute the modified snmpd.conf file and the OSX_Inventory.sh file to all clients and maintain them (you had to do it with snmpd.conf anyway)
  4. Don’t forget to start the SNMPd service at boot on your client system
  5. Don’t forget to restart the SNMPd service after making changes to your snmpd.conf file or you will not see the results of any changes