5

I required a SNMP agent in python, which listen on a particular port and and responds to basic SNMP command (like GTE, SET, GETNEXT ...etc)

If any one have code please reply on this post.

aloksinghk
  • 101
  • 1
  • 2
  • 7
  • [pysnmp command responder](http://pysnmp.sourceforge.net/examples/current/v3arch/agent/cmdrsp/v3-multiple-users.html) and [look at the nullege source of zabbix](http://www.nullege.com/codes/show/src%40z%40a%40zabbixSNMP-creator-HEAD%40src%40zabbixsnmp_creator.py/34/pysnmp/python). pysnmp command responder code will work like a charm – Rahul Gautam Apr 25 '13 at 11:39
  • I checkd Command Responder script but My aim is to read OID from a txt file and reply to get/getnext etc request. if set request come then it should write OID in file. I am not getting how command responder is reading OID and from where – aloksinghk Apr 29 '13 at 06:04
  • [take a good look at example](http://pysnmp.sourceforge.net/examples/current/v3arch/agent/cmdrsp/v2c-custom-scalar-mib-objects.html), in which MIB loads by `mibBuilder.importSymbols('SNMP-V2-SMI')`. – Rahul Gautam Apr 29 '13 at 13:00
  • And convert mib in pysnmp format `smidump -f python | libsmi2pysnmp > ` – Rahul Gautam Apr 29 '13 at 13:06

3 Answers3

4

There's a collection of SNMP Command Responder scripts at pysnmp web-site.

Here's a simple PySNMP-based Command Responder that uses text files in /tmp as a MIB data store.

from pysnmp.entity import engine, config
from pysnmp.entity.rfc3413 import cmdrsp, context
from pysnmp.carrier.asynsock.dgram import udp
from pysnmp.smi import instrum, error
from pysnmp.proto.api import v2c

snmpEngine = engine.SnmpEngine()

config.addSocketTransport(
    snmpEngine,
    udp.domainName,
    udp.UdpTransport().openServerMode(('127.0.0.1', 1161))
)

config.addV1System(snmpEngine, 'my-area', 'public', contextName='my-context')

config.addVacmUser(snmpEngine, 2, 'my-area', 'noAuthNoPriv', (1,3,6), (1,3,6))

snmpContext = context.SnmpContext(snmpEngine)

class FileInstrumController(instrum.AbstractMibInstrumController):
    def readVars(self, vars, acInfo=(None, None)):
        try:
            return [ (o,v2c.OctetString(open('/tmp/%s.txt' % o, 'r').read())) for o,v in vars ]
        except IOError:
            raise error.SmiError

    def writeVars(self, vars, acInfo=(None, None)):
        try:
            for o,v in vars:
                open('/tmp/%s.txt' % o, 'w').write(str(v))
            return vars
        except IOError:
            raise error.SmiError

snmpContext.registerContextName(
    v2c.OctetString('my-context'),          # Context Name
    FileInstrumController()                 # Management Instrumentation
)

cmdrsp.GetCommandResponder(snmpEngine, snmpContext)
cmdrsp.SetCommandResponder(snmpEngine, snmpContext)

snmpEngine.transportDispatcher.jobStarted(1)

try:
    snmpEngine.transportDispatcher.runDispatcher()
except:
    snmpEngine.transportDispatcher.closeDispatcher()
    raise

Keep in mind that this script is just a starter for you, it does not handle some corner cases.

Ilya Etingof
  • 5,440
  • 1
  • 17
  • 21
  • I checkd Command Responder script but My aim is to read OID from a txt file and reply to get/getnext etc request. if set request come then it should write OID in file. I am not getting how command responder is reading OID and from where. – aloksinghk Apr 29 '13 at 06:01
  • The script above writes values into text files named after OIDs (in /tmp) and reads values from there on GET. This happens in readVars() & writeVars() methods. – Ilya Etingof May 06 '13 at 14:19
0
#!/bin/bash
PLACE=".1.3.6.1.4.1.1023.1.2.1"
REQ="$2"    # Requested OID
VALUE_STORAGE="/tmp/snmp_value_storage.txt"




# Check if the value storage file exists, if not, create it
if [ ! -f "$VALUE_STORAGE" ]; then
    touch $VALUE_STORAGE
fi

# Function to get value from the value storage
get_value_from_storage() {
    OID=$1
    grep "^$OID" $VALUE_STORAGE | cut -d' ' -f2
}

# Function to set value to the value storage
set_value_to_storage() {
    OID=$1
    VALUE=$2
    if grep -q "^$OID" $VALUE_STORAGE; then
        sed -i "s/^$OID.*/$OID $VALUE/" $VALUE_STORAGE
    else
        echo "$OID $VALUE" >> $VALUE_STORAGE
    fi
}

# Process SET requests by saving the assigned value to the value storage
if [ "$1" = "-s" ]; then
    set_value_to_storage $REQ $4
    exit 0
fi
#
#  GETNEXT requests - determine next valid instance
#
if [ "$1" = "-n" ]; then
  case "$REQ" in
    $PLACE|             \
    $PLACE.0|           \
    $PLACE.0.*|         \
    $PLACE.1)       RET=$PLACE.1.0 ;;     # netSnmpPassString.0
    
    $PLACE.1.*|         \
    $PLACE.2|           \
    $PLACE.2.0|         \
    $PLACE.2.0.*|       \
    $PLACE.2.1|         \
    $PLACE.2.1.0|       \
    $PLACE.2.1.0.*|     \
    $PLACE.2.1.1|       \
    $PLACE.2.1.1.*|     \
    $PLACE.2.1.2|       \
    $PLACE.2.1.2.0) RET=$PLACE.2.1.2.1 ;; # netSnmpPassInteger.1

    $PLACE.2.1.2.*|     \
    $PLACE.2.1.3|       \
    $PLACE.2.1.3.0) RET=$PLACE.2.1.3.1 ;; # netSnmpPassOID.1

    $PLACE.2.*|         \
    $PLACE.3)       RET=$PLACE.3.0 ;;     # netSnmpPassTimeTicks.0
    $PLACE.3.*|         \
    $PLACE.4)       RET=$PLACE.4.0 ;;     # netSnmpPassIpAddress.0
    $PLACE.4.*|         \
    $PLACE.5)       RET=$PLACE.5.0 ;;     # netSnmpPassCounter.0
    $PLACE.5.*|         \
    $PLACE.6)       RET=$PLACE.6.0 ;;     # netSnmpPassGauge.0

    *)              exit 0 ;;
 esac
else

#
#  GET requests - check for valid instance
#

  case "$REQ" in
    $PLACE.1.0|         \
    $PLACE.2.1.2.1|     \
    $PLACE.2.1.3.1|     \
    $PLACE.3.0|         \
    $PLACE.4.0|         \
    $PLACE.5.0|         \
    $PLACE.6.0)     RET=$REQ ;;
    *)              exit 0 ;;
  esac
fi
# Process SET requests by saving the assigned value to the value storage
if [ "$1" = "-s" ]; then
    case "$REQ" in
        $PLACE.3.0) set_value_to_storage $REQ $4; exit 0 ;;
        $PLACE.4.0) set_value_to_storage $REQ $4; exit 0 ;;
        *)          exit 0 ;;
    esac
fi

#
#  "Process" GET* requests - return hard-coded value
#

 echo "$RET"
 case "$RET" in
 $PLACE.1.0)      echo "string";  echo "ntp status: active";               exit 0 ;;
 $PLACE.2.1.2.1 ) echo "string";  echo "since Fri ess2023-04-07 "          exit 0 ;;
 $PLACE.2.1.3.1)  echo "integer"; echo "1";                                exit 0 ;;
 $PLACE.3.0)      echo "string";  echo "$(get_value_from_storage $RET '')";                exit 0 ;;
 $PLACE.4.0)      echo "string";  echo "$(get_value_from_storage $RET '')";                exit 0 ;;
  $PLACE.5.0)     echo "counter";   echo "42";                                 exit 0 ;;
  $PLACE.6.0)     echo "gauge";     echo "42";                                 exit 0 ;;
  *)              echo "string";    echo "ack... $RET $REQ";                   exit 0 ;;  # Should not happen
esac

it performs the writing and reading operations to the file according to these script commands

  • As it’s currently written, your answer is unclear. Please [edit] to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community May 29 '23 at 11:37
-2
import socket
import netsnmp
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1)
s.bind((HOST, PORT)) #give host ip and port no:
s.listen(2)

conn, addr = s.accept()
data = conn.recv(1024)
bindvariable = netsnmp.Varbind("give full oid here")
xx = netsnmp.snmpget(bindvariable, Version = 2, DestHost = '192.168.0.216', Community='private')

similarly you can use snmpset and walk also

kelvin
  • 149
  • 7
  • 3
    This seems a little confusing. I'm not a Python programmer, but the above code seems to 1. open a TCP socket 2. send an SNMP get-request None of those two are relevant for an SNMP Agent. Please read the relevant RFCs (for example 1905) to develop some basic SNMP knowledge before answering questions about it. – Jolta Jun 13 '13 at 08:08