<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
		<id>https://dreness.com/wikimedia/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Btimby</id>
		<title>Wikifications - User contributions [en]</title>
		<link rel="self" type="application/atom+xml" href="https://dreness.com/wikimedia/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Btimby"/>
		<link rel="alternate" type="text/html" href="https://dreness.com/wikimedia/index.php?title=Special:Contributions/Btimby"/>
		<updated>2026-05-23T14:18:07Z</updated>
		<subtitle>User contributions</subtitle>
		<generator>MediaWiki 1.26.3</generator>

	<entry>
		<id>https://dreness.com/wikimedia/index.php?title=Net_SNMP&amp;diff=1291</id>
		<title>Net SNMP</title>
		<link rel="alternate" type="text/html" href="https://dreness.com/wikimedia/index.php?title=Net_SNMP&amp;diff=1291"/>
				<updated>2009-02-12T13:43:46Z</updated>
		
		<summary type="html">&lt;p&gt;Btimby: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;In investigating how to dynamically produce data that I could plumb via snmp, it became quickly apparent that the snmpd shipped on Intel macs in 10.4.* is pretty well busted. It only supports a very small subset of the functionality provided by the net-snmp daemon in general (i.e. on other platforms). This can be observed by running snmpd with the -H switch. Notable omissions include &amp;#039;exec&amp;#039; and &amp;#039;extend&amp;#039;, for example, which are typically used to easily fork off arbitrary sub processes tasked with collecting data for the targeted OID or range of OIDs.&lt;br /&gt;
&lt;br /&gt;
It was quickly obvious that we&amp;#039;d have to use the macports snmpd. That version does have support for more functionality than the one shipped with Mac OS X, but it&amp;#039;s *missing* exec and extend! But wait! What&amp;#039;s this about &amp;#039;pass&amp;#039; and &amp;#039;pass_persist&amp;#039;? They are similar to &amp;#039;exec&amp;#039; except that pass and pass_persist allow the script to dynamically define the OID hierarchy. This is different from exec; with exec you call out the specific OID to script mappings in the config file. With pass_persist, the script takes control of an entire &amp;#039;tree&amp;#039;, and is responsible for responding for any OIDs under that tree.&lt;br /&gt;
&lt;br /&gt;
To use pass_persist, we need a script that can speak the net-snmp pass_persist protocol, which is described in the snmpd.conf(5) man page.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;       pass_persist [-p priority] MIBOID PROG&lt;br /&gt;
              will also pass control of the subtree rooted at  MIBOID  to  the&lt;br /&gt;
              specified  PROG  command.  However this command will continue to&lt;br /&gt;
              run after the initial request has been answered,  so  subsequent&lt;br /&gt;
              requests can be processed without the startup overheads.&lt;br /&gt;
&lt;br /&gt;
              Upon  initialization, PROG will be passed the string &amp;quot;PING\n&amp;quot; on&lt;br /&gt;
              stdin, and should respond by printing &amp;quot;PONG\n&amp;quot; to stdout.&lt;br /&gt;
&lt;br /&gt;
              For GET and GETNEXT requests, PROG will be passed two  lines  on&lt;br /&gt;
              stdin,  the  command (get or getnext) and the requested OID.  It&lt;br /&gt;
              should respond by printing three lines to stdout - the  OID  for&lt;br /&gt;
              the  result  varbind, the TYPE and the VALUE itself - exactly as&lt;br /&gt;
              for the pass directive above.  If the command cannot  return  an&lt;br /&gt;
              appropriate  varbind,  it  should print print &amp;quot;NONE\n&amp;quot; to stdout&lt;br /&gt;
              (but continue running).&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
One bit of information that is missing from the man page is the shutdown sequence employed. For example, when snmpd is stopping, how does it inform the pass-persist agents of that? Well, it sends a blank line to the agent, this signals that the agent should shut down. A sample script might look something like this - note, this is just proof of concept (does not implement getnext, for example):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;#!/usr/bin/python -u&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;This is a python backend for snmp&amp;#039;s &amp;quot;pass_persist&amp;quot; function. It is critical&lt;br /&gt;
that the python interpreter be invoked with unbuffered STDIN and STDOUT by use&lt;br /&gt;
of the -u switch in the shebang line.&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
import sys&lt;br /&gt;
from select import select&lt;br /&gt;
&lt;br /&gt;
def readStdin () :&lt;br /&gt;
  &amp;#039;&amp;#039;&amp;#039;Read from standard input. Use &amp;quot;select&amp;quot; to wait for new data&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
  (rr, wr, er) = select([sys.stdin], [], [])&lt;br /&gt;
  for fd in rr:&lt;br /&gt;
    line = fd.readline()&lt;br /&gt;
    processInput(line)&lt;br /&gt;
&lt;br /&gt;
def processInput (line) :&lt;br /&gt;
  &amp;#039;&amp;#039;&amp;#039;Examine input, call subroutines&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
  if line.strip() == &amp;#039;&amp;#039;:&lt;br /&gt;
    sys.exit(0)&lt;br /&gt;
  if &amp;#039;PING&amp;#039; in line :&lt;br /&gt;
    playPingPong()&lt;br /&gt;
  if &amp;#039;get&amp;#039; in line :&lt;br /&gt;
    target = sys.stdin.readline()&lt;br /&gt;
    doGet(target)&lt;br /&gt;
&lt;br /&gt;
def playPingPong () :&lt;br /&gt;
  &amp;#039;&amp;#039;&amp;#039;Perform the snmpd secret handshake&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
  print &amp;#039;PONG&amp;#039;&lt;br /&gt;
&lt;br /&gt;
def doGet(target) :&lt;br /&gt;
  &amp;#039;&amp;#039;&amp;#039;Process a &amp;quot;get&amp;quot; request&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
  print target,&lt;br /&gt;
  print &amp;#039;integer&amp;#039;&lt;br /&gt;
  print &amp;#039;42&amp;#039;&lt;br /&gt;
&lt;br /&gt;
# loop&lt;br /&gt;
while 1 : readStdin()&amp;lt;/pre&amp;gt;&lt;br /&gt;
Next, we add an entry in the snmpd config file, associating an SNMP OID tree with our script:&lt;br /&gt;
&amp;lt;pre&amp;gt;pass_persist .1.3.6.1.4.1.2021.255 /path/to/persist_test.py&amp;lt;/pre&amp;gt;&lt;br /&gt;
Now let&amp;#039;s start snmpd in a debug mode, asking for details about the pass_persist backend:&lt;br /&gt;
&amp;lt;pre&amp;gt;snmpd -c /etc/snmpd.conf --logTimeStamp=true -f -Lf /tmp/snmpd.log \&lt;br /&gt;
-Ducd-snmp/pass_persist,ucd-snmp/pass,snmpd,output,helper:debug&amp;lt;/pre&amp;gt;&lt;br /&gt;
Tail that log file in one window, and make an snmp request in another.&lt;br /&gt;
&amp;lt;pre&amp;gt;snmpget -v 1 -c &amp;lt;community&amp;gt; localhost .1.3.6.1.4.1.2021.255.2&amp;lt;/pre&amp;gt;&lt;br /&gt;
In the snmpd debug log, we see:&lt;br /&gt;
&amp;lt;pre&amp;gt;2007-06-29 16:06:09 ucd-snmp/pass_persist: open_persist_pipe(1,&amp;#039;/path/to/persist_test.py&amp;#039;)&lt;br /&gt;
2007-06-29 16:06:09 ucd-snmp/pass_persist: persistpass-sending:&lt;br /&gt;
get&lt;br /&gt;
.1.3.6.1.4.1.2021.255.2&amp;lt;/pre&amp;gt;&lt;br /&gt;
... and then a response to our snmp query:&lt;br /&gt;
&amp;lt;pre&amp;gt;UCD-SNMP-MIB::ucdavis.255.2 = INTEGER: 42&amp;lt;/pre&amp;gt;&lt;br /&gt;
Sweet!&lt;/div&gt;</summary>
		<author><name>Btimby</name></author>	</entry>

	</feed>