How to implement SET and TRAP in agent side with pysnmp? - snmp

I have implemented a SNMP Agent using pysnmp based on this example. This example demonstrates SNMP GET and GETNEXT queries. But I have found no pointer how can I implement SNMP SET and TRAP on top of this code. Examples I have found for SET and TRAP are completely different implementation. How can I implement SNMP SET and TRAP on top of this code?

Assuming you want to combine SNMP CommandResponder (which you have already implemented) with SNMP NotificationReceiver, look at this example. You basically can join both examples within the same Python module around a single I/O loop (e.g. transport dispatcher).
However, typically, NotificationReceiver resides at the NMS while CommandResponder is SNMP agent running inside the managed software/device.
Supporting SNMP SET within your existing code would require refactoring the way how your MIB objects are stored. With current example they are kept in a non-writeable storage (tuple) and the MIB objects are not designed to change their stored value (they return a constant). So you need to change that one way or the other.
Otherwise supporting SNMP SET is simple - just add condition like this:
...
elif reqPDU.isSameTypeWith(pMod.SetRequestPDU()):
for oid, val in pMod.apiPDU.getVarBinds(reqPDU):
if oid in mibInstrIdx:
# put your MIB instrumentation update code here
# smith like this, but not exactly:
mibInstrIdx[oid] = mibInstrIdx[oid].clone(val)
varBinds.append((oid, mibInstrIdx[oid](msgVer)))
else:
# No such instance
varBinds.append((oid, val))
pendingErrors.append(
(pMod.apiPDU.setNoSuchInstanceError, errorIndex)
)
break
into your cbFun.

Related

How to change parameters Runtime in Omnet++ with setDoubleValue()

I am simulating a network with 2 wireless hosts and 1 Access point. During runtime a node sets the Access Point's transmit power to zero (to turn it off) by accessing the module and using setDoubleValue(0). But the new values never takes effect. AP's msgs continue to reach the nodes. What am I doing wrong here? I want to turn access point off while the simulation is running. Please help.
cSimulation *currentSimulation = getSimulation();
cModule *tx = nullptr;
tx=currentSimulation->getModuleByPath("agranet.ap.wlan[0].radio.transmitter");
tx->par("power").setDoubleValue(0);
//cPar& po = tx->par("power");
//po.setDoubleValue(0);
I want to turn the access point off while simulation is running.
You cannot change the power parameter after initialization because it is a non-volatile parameter, so its value is read at initialization and cached afterwards. You can manipulate only volatile NED parameters where the C++ code is already prepared for this.
On the other hand, what you are trying to achieve is to disable a node at a certain time, which is what ScenaioManager is for:
https://inet.omnetpp.org/docs/users-guide/ch-scenario-scripting.html

How can I properly respond with a null value to an SNMP (2c) GetRequest?

I am developing an SNMP (2c) agent for a sensor product. I'm just learning about SNMP and MIB formats and struggling to represent a particular value that could be unknown.
For example, I've defined a temperature OBJECT-TYPE as an Integer32 but sometimes the value is not available or unknown. If I respond with a null value, the SNMP manager times out*. I would prefer to use a null value when the temperature value is unknown or not available, instead of agreeing upon some specific value to mean the same thing.
This leads me to the following questions:
Does SNMP v2c/MIB support a data type that is analogous to a nullable integer?
If so, what is the proper way to denote this in the MIB?
* I am using MG-SOFT's MIB Browser to get values as a testing method. If the value is null, it times out (even though the agent responded). If the value is an integer, it works as expected. I am using nSoftware IP*Works! SNMP library to develop the agent.
Posting from comment:
You should not be doing this. OID values should always be singular they should not be dynamically changed, if someone will use a mibfile for this it will be incorrect and misleading for the person who is implementing communication protocol for this sensor. The correct way to do it is to have 2 OIDs one with the value and another with the status of the sensor.
In experimenting, I've had some success dynamically changing the SNMP agent object type:
int? temperature = ReadTemperature();
snmpAgent.Objects[i].Value = temperature.ToString();
snmpAgent.Objects[i].ObjectType = temperature.HasValue ? SNMPObjectTypes.otInteger : SNMPObjectTypes.otNull;
When performing a GetRequest with a MIB browser, it appears to handle both cases. Even though the MIB doesn't specify that the particular OID can be null, just SYNTAX Integer32, it seems to work. Various SNMP managers will probably behave differently.
(This example is specific to IPWorks SNMP Agent.)

What's the meaning of mutex_.AssertHeld() in source of leveldb

Recently I read the source of leveldb, the source url is https://leveldb.googlecode.com/files/leveldb-1.13.0.tar.gz
And when I read db/db_impl.cc,there comes the following code:
mutex_.AssertHeld()
I follow it into file port/port_posix.h,and I find the following :
void AssertHeld() { }
Then I grep in the souce dir,but can't find anyother implementation of the AssertHeld() anymore.
So here is my question,what does the mutex_.AssertHeld() do in db/db_impl.cc? THX
As you have observed it does nothing in the default implementation. The function seems to be a placeholder for checking whether a particular thread holds a mutex and optionally abort if it doesn't. This would be equivalent to the normal asserts we use for variables but applied on mutexes.
I think the reason it is not implemented yet is we don't have an equivalent light weight function to assert whether a thread holds a lock in pthread_mutex_t used in the default implementation. Some platforms which has that capability could fill this implementation as part of porting process. Searching online I did find some implementation for this function in the windows port of leveldb. I can see one way to implement it using a wrapper class over pthread_mutex_t and setting some sort of a thread id variable to indicate which thread(s) currently holds the mutex, but it will have to be carefully implemented given the race conditions that can arise.

When to use network system calls vs. sk_buff within a KM

While trying to learn more about linux kernel networking ... I have a kernel module that contains a protocol which runs on top of TCP. Its almost an application layer protocol I'm experimenting with. The calls are passed in via the normal system call interface as executed from userspace.
So network calls from within my (layer above TCP) module generally look like this ...
ret = sock->ops->connect(sock, (struct sockaddr *) &myprot.daddr,
sizeof(myprot.daddr), flags);
I've used sendmsg/recvmsg successfully within my KM to send and receive data from a client to a server (from two separate kernel instances). The calls within the KM generally looks as follows:
ret = sock->ops->sendmsg(iocb, myprot.skt, &msg, sizeof(struct msghdr));
ret = sock->ops->recvmsg(iocb, sock, msg, total_len, flags);
What I'm trying to understand now is how and when to use sk_buff to do the same thing. I.e. when to use system calls such as what I use above, and when to directly access the network stack via sk_buff to send and receive data.
I've found many examples of how to send and receive data from within transport layers using sk_buff, but nothing from a layer above the transport that is also contained in a kernel module and using sk_buff.
Update for clarification.
I've overridden struct proto_ops and replaced the member methods for my own protocols use which do correspond to system calls from user space. I do understand that sk_buff is the buffer system for the kernel and is where packets are enqueued. However. I don't see any reason why I can't use the protocol-specific functions of struct proto_ops which also handles sockets and the data enqueued on them (though at a higher level). So it seems to me there are two ways to access sk_buffs depending upon where one wants to access them.
If I'm working in the transport layer and want to access data anywheres within the network stack (e.g. transport, ip, mac), I could directly access sk_buffs, but if I am working above the transport layer, I would use the abstracted protocol specific member functions that correspond to system calls. After all, they both eventually work on sk_buffs.
I guess my confusion, or what I'm trying to confirm that I'm doing right or wrong by knowing the difference in these two ways to access sk_buffs and from where, is ... if I'm sending data over a transport from TCP within the kernel, than I can just make use of the proto_ops system calls that relate to TCP unless I need more control in which I would then make use of the lower level skb functions to manage the queues.
Not sure to understand because you want to use to different things for the same purpose. The proto_ops in sock->ops are operations invoked during the correspondent system call. The sk_buff is the socket buffer system of the kernel; it is the place where packet are enqueued.
There is not the possibility to do the same thing of proto_ops with sk_buff, if it should be possible one of these structures is useless.

How do I port a serial port device driver from Linux 2.6.21 to 2.6.36?

It appears that some time between these two kernels a lot of data structures were changed, and it breaks my driver in several places.
First, in 2.6.21 the struct uart_port had a field "struct uart_info *info" which I relied on in several places. I test several places to make sure it is non-null, and if non-null I additionally test if it's sub-field (struct tty_struct *tty) is non-null, and I uses these to check if flow control is enabled and if we are stopped transmitting.
In 2.6.36 the info back pointer has been removed and I'm not sure how to get at it, or if the semantics of what I am trying to do are even valid any more, as the only serial driver that even uses this appears to have ifdef'ed out the code dealing with it, and additionally holds all this data in its own structures (how does that work to even correctly maintain state with the kernel)???
Additionally, save_and_cli() and restore_flags() are missing. I see new functions local_irq_save() and local_irq_restore(), can I just switch to using those, or are there any gotchas?
Finally, __ioremap is missing. Looks like maybe ioremap_noncache is the replacement, but again I'm not sure if there are any semantic differences or gotchas. I would assume I don't want ioremap() since I am talking directly to hardware, but some other drivers appear to do so and I don't know why that would work.
Looking at how an in-tree driver that uses the same functionality has changed between the two versions is usually the best way to go. For example, the ioc4_serial driver uses the info member of struct uart_port in kernel 2.6.21, but has switched to using the struct uart_state *state member by kernel 2.6.36.
That driver obtains the tty_struct with:
state = the_port->state;
tty = state->port.tty;

Resources