What is a SNMP ping? - networking

I know what SNMP is and I know what ping is. What is meant by a 'SNMP ping'? SNMP can be used to see if devices on a network are still alive.. what does it use to do this? I wouldn't have thought an SNMP ping is the same as an ICMP ping?

As you correctly suspected SNMP "ping" is definitely not the same as ICMP ping. What it does is to try to retrieve some basic information through SNMP like DNS name, system name, location, system type, system description etc. and if successful the "ping" is deemed to be successful too.
But this is not any kind of standard the way ICMP Ping (echo) is. There is no special "ping" command in SNMP - it's just a name for a tool used to scan whether SNMP is alive at some target device (by retrieving some common MIB values). So as you would expect the implementation differs too as a consequence of it being a useful tool rather than a standard.
But that has little effect in practice as there is a set of 'mandatory' SNMP records so if a device does not respond to those, you can be pretty sure it doesn't run SNMP. For an SNMP "ping" to work SNMP MUST be enabled on the target device of course ... which isn't the case by default most of the time in general so that's a big difference to ICMP Ping which can be used almost universally.
I hope I answered your question

Ping was "Packetized Internet Node Groper", originally a tool that implemented an ICMP echo response. "Ping" is now commonly used to convey an abstraction of checking whether a device is online, available, responding.
There are MIB options to ask a device to ping or trace route something -- which seem to be asking a device to ICMP to a third party and indicate success/failure -- but the colloquial use of "snmp ping" is to check responsiveness by asking a simple SNMP question of a static data point and get a response.
Most devices offer some response to requests in the 1.3.6.1.2 subtree, but it's not a hard/fast requirement. For example, on a Unix (-like) command line, one may try "snmpget -v 1 -c public 192.168.0.1 1.3.6.1.2.1.1.1.0" to ask "192.168.0.1" what its name is. The device may respond; it typically will not NAK if the access (version 1, community string "public", in this case) is incorrect. The switch(es) in between may choose to alert the requestor "unreachable", but may not. In this case as others, if there is no response, the messages or hints aside from "no response" may be helpful.

It is typical for an SNMP ping to be equivalent to an ICMP echo. IBM states, for example, that it issues a single ICMP echo (to the SNMPD on the receiving end) and returns the minRTT. If a response times out, then it sends another raw echo packet after 1 second, and another again after 2 seconds. If there is yet no reponse, -1 is returned.
Cisco also has a sort of similar implementation (SNMP GET/SET/PING-MIB). It is definitely implementation-specific, however.
Source

"ping" is just a generic term for sending a message for the purpose of seeing whether you get back a response.
ICMP is the most common method of "pinging" a host on an IP network. If you get an ICMP echo response from an IP address, then you know that something out there is able and willing to receive and reply to at least some network traffic for that address. Receiving a reply to an ICMP ping does not tell you anything about the state of any other network services. Not receiving a reply does not tell you anything at all: there are dozens of reasons why you might not receive a response to an ICMP ping at any particular moment.
The concept of a "ping" applies to any mechanism of communication. Some network protocols have specific standards for performing a "ping". For most, "pinging" just means trying to perform some basic operation to see if it works. For example, you could "ping" an HTTP server by just connecting to port 80 and doing "HEAD / HTTP/1.0". If you get back an HTTP response, then you know there's an HTTP server operational. The same idea applies to SNMP or any another network application.

In most contexts I have heard 'SNMP Ping' used, it was referring to a DISMAN PING. This method allows you to use SNMP to control a device or host remotely and tell it to 'ping' another device. Typically, this would be a traditional ICMP ping.
For example, imagine you are on your laptop, and you have a webserver which seems to be taking a long time to load a page. You can't quickly tell if it is a problem with the network between you and the webserver, the network between the webserver and the database, or something with one of the servers themselves. You want to eliminate network first, so you first ping the webserver from your laptop. No loss, and the latency looks reasonable. You ping the database server from your laptop, and it looks good too. The problem with the laptop-database ping test is it doesn't tell you what is going on between the webserver and the database. Ideally, you'd log into the webserver and ping the database, but you don't have a shell account. You do, however, have a read/write SNMP access. So, you decide to use 'snmpset' from your laptop to the webserver to create a table (for ping results) and specify a target (database server) to ping. The webserver snmpd initiates an ICMP ping from the webserver to the database and stores the results in a table. You then do a 'snmpget' from the laptop to pull the webserver-database ping results.
The other contexts you might see 'snmp ping' may be simply a snmpget from a SNMP client to a SNMP daemon to confirm SNMP is working.

In my understanding, an SNMP ping is the one defined in RFC 2925
https://www.rfc-editor.org/rfc/rfc2925
If the SNMP agent vendor indicates that a device supports this RFC, then you can use SNMP ping to monitor it. Otherwise, it won't work.
This is completely different from the "normal ping" (ICMP based).

Like ICMP ping, SNMP ping, just a form of a SNMP getrequest, is used to check the aliveness of any equipment that has standard SNMP agent running for monitoring. It is useful when the management systems that manage these equipments to query for the auto discovery. Any sysOid can be used to query the equipment as part of the request.

Related

How can I know if the packet I send is received when I'm using UDP?

I know UDP is not a two-way communication between client & server. However, if I send a packet to clients from a server, how can I know that my packet reach it's destination?
The only way to be sure that the data you've send are received (and processed) by the server application is to let the server application explicitly acknowledge the data in a reply.
Note that contrary to a comment to your question it will not help to use TCP instead of UDP to get a more reliable transport: while your OS kernel will does its best to deliver data with TCP (instead of just trying once with UDP) it can neither guarantee the delivery (since connectivity might break) nor does it care if the server application itself has read and maybe also processed the data. The only way to know that the application has successfully read the data is to let the application itself say so.

Reply with unsupported protocol when writing custom network stack

I have been writing my own version of the 802.11 protocol with network stack. This is mostly a learning experience to see more in depth on how networks work.
My question is, is there a standard for replying to client devices that a certain protocol is unsupported?
I have an android device connecting to my custom wifi device and immediately sending a TON of requests at the DNS port of my UDP protocol. Since I would like to test out other protocols I would very much like a way for my wifi device to tell the android device that DNS is not available and get it to quite down a little.
Thanks in advance!
I don't see a possibility to send a reply that a service is not available.
I can't find anything about this case in the UDP specification.
One part of the DNS specification assumes that there are multiple DNS servers and defines how to handle communication with them. This explains part of the behavior in your network, but does not provide much information how to handle it.
4.2.1 Messages - format - UDP usage
The optimal UDP retransmission policy will vary with performance of the
Internet and the needs of the client, but the following are recommended:
The client should try other servers and server addresses
before repeating a query to a specific address of a server.
The retransmission interval should be based on prior
statistics if possible. Too aggressive retransmission can
easily slow responses for the community at large. Depending
on how well connected the client is to its expected servers,
the minimum retransmission interval should be 2-5 seconds.
7.2 Resolver Implementation - sending the queries
If a resolver gets a server error or other bizarre response
from a name server, it should remove it from SLIST, and may
wish to schedule an immediate transmission to the next
candidate server address.
According to this you could try to send garbage back to the client, but this is rather a hack, or an error, but how does an error look like? Such a solution assumes that you have knowledge about the service that you don't support.
I believe that the DNS - requests can be avoided by using DHCP. DHCP allows to specify DNS-servers as listed in the linked page. This is the usual way that I know for a DNS-resolver in a LAN to get initial DNS servers although I don't find anything about this in the DNS specification. You can give the Android - device a DNS-server with DHCP so that it does to need to try to query your device. Querying your device could be a fallback.
Additionally to DNS there is mDNS which uses multicasts in the network to send queries. This seems not to be the protocol you have to do with because it uses the special port 5353.
Not possible to stop DNS in the way you intend. However, only for your tests you can check the UDP messages and find out the names the device is looking for. Then you update the hosts file (google how to do it: http://www.howtogeek.com/140576/how-to-edit-the-hosts-file-on-android-and-block-web-sites/) and add those names with some localoop IP address. That might work for your test.
Other possibility is to change DNS server to some localloop IP address: http://xslab.com/2013/08/how-to-change-dns-settings-on-android/
Again, this is only to avoid having all the DNS messages through the wifi connection.

Is it possible to build an arp request packet in such a way that will cause a router to forward it over subnets?

What I'm trying to do is get all the ip addresses in my network, and I thought, assuming I know the address of all subnets could use arp requests to achieve that if there was a way to forward these requests over different subnets.
For example , assume I had two hosts
192.168.0.2/24 and 192.168.1.2/24
connected via router using IP addresses 192.168.0.1/16 192.168.1.1/16.
I would like to send an arp request from 192.168.0.2/16 to 192.168.1.2/16.
I thought maybe if the arp request was encapsulated in layer 3 header containing 192.168.1.2/24, or 192.168.1.255/24 as the dsetination this will work.
If it is possible and you know a tool that does that I will be happy to know about this tool.
If it isn't, I would like to know what happens to a packet like the one I described above
I would like to know what happens to a packet like the one I described above
If you encapsulate some info into standard IP-packet, then, naturally, it will be routed to the IP-destination host. Yet if the remote host knew nothing about this non-standard packet, then nothing would happen.
If you really want to get something out of this, you need to have up and running some software server on that remote host, which is able to process your requests. That is, you need some Proxy ARP: either existing implementation, or made of your own.
If you don't have such "an agent" in the target subnetwork, then you're out of luck. Go with sequential IP-scanning until be banned by admin.

Nat punch, MasterServer/Server/Client. Client can't talk to Server on known public ip and port

I have 3 applications: a MasterServer, a Server and a Client.
The MasterServer is running on: 70.105.155.5:15555 (port forwarded with UPnP)
I create a server and let the MasterServer know I exist. The MasterServer keeps my public ip and port. The port that the MS gets is randomly assigned by my router (lets say: 70.105.155.5:16666). The server keeps messaging the MasterServer each 10sec to keep that same port open.
I open up the client, on which it asks the MasterServer for the public ip and port of a server. The MasterServer returns: 70.105.155.5:16666. I know 100% sure that the server's public port 16666 is still open because I can check that in my logs.
But all messages sent from Client => Server are never received. At the same time the Server is still getting messages from MasterServer through 16666.
So this is really puzzling. Am I forgetting something? Is my understanding of NAT punch flawed?
Thanks for any help!
There are multiple issues here, and it depends on the router's security configuration too, often in ways the user cannot control. The general excuse is that it's a security precaution, but really firewalling and NAT are two separate concerns. Anyway, most home users are stuck with whatever they've got. They do usually have the option to explicitly map a port, and UPnP can help you too if the router supports it.
But going back to NAT, to begin with you're likely to have a problem if your server and client are sitting behind the same NAT, which seems to be the case given the addresses you quoted above. Most NATs only rewrite incoming packets from the public interface - so packets that physically arrive on the private interface, even if they're addressed to the public IP, won't be forwarded. To support this configuration in the wild you need the devices to advertise their private addresses to the MasterServer, and detect when they want to talk to other devices behind the same NAT, and if so, use the private address rather than going through the NAT. This is flawed in many ways, especially with nested NATs, but I think it's the best you can do.
Beyond that, in the more common case where all the devices are behind different NATs, some routers will only allow incoming traffic on a forwarding port if it's from the place they originally sent the outgoing traffic to (which resulted in the port opening up in the first place). Some also require it to come from the same source port on the remote device.
The workaround is for the MasterServer to do a bit more work. The gist is that it should tell both peers to send a packet to each other; these may or may not get through, but simply sending the packet out through the Server's NAT to the Client's public IP address may be enough to get the Server's NAT to correctly forward later packets from the Client. And vice versa.
In practice it is even more complicated, because the Server's NAT may use a different port when talking to Client to what it used when talking to MasterServer. So while this may open up a port for the Client to talk back to the Server, but it might not be the one the Client is expecting to use. If the NAT behaves like this, then you need to look at how predictable its choice of port numbering is. Some just increase one by one (but bear in mind there may be other devices behind the same NAT causing the number to jump more than one step at a time). For these ones, the Client needs to spam a range of Server ports to try to figure out which one got opened up. Again the MasterServer is in the best position to coordinate this.
Others seem totally random in port allocations, and there's not much you can do with those. But it's only terminal if both ends are behind these random NATs. So long as one end is more amenable to being opened up, the random end won't matter.
Also note that some NATs use a different outgoing port for each port on the target - this also makes prediction a lot harder, even in the case that the ports are not randomly assigned. Again, so long as one end of the connection is flexible, you can tolerate these NATs but in a peer-to-peer context they will be a nightmare in the end because they just can't talk to each other.

Determining when to try an IPv6 connection and when to use IPv4

I'm working on a network client program that connects to public servers, specified by the user. If the user gives me a hostname to connect to that has both IPv4 and IPv6 addresses (commonly, a DNS name with both A and AAAA records), I'm not sure how I should decide which address I should connect to.
The problem is that it's quite common for machines to support both IPv4 and IPv6, but only to have global connectivity over IPv4. The most common case of this is when only IPv6 link-local addresses are configured. At the moment the best alternatives I can come up with are:
Try the IPv6 address(es) first - if the connection fails, try the IPv4 address(es); or
Just let the user specify it as a config setting ("prefer_ipv6" versus "prefer_ipv4").
The problem I can see with option 1 is that the connection might not fail straight away - it might take quite a while to time out.
Please do try IPv6. In the significant majority of installations, trying to create an IPv6 connection will fail right away if it can't succeed for some reason:
if the system doesn't support IPv6 sockets, creating the socket will fail
if the system does support IPv6, and has link-local addresses configured, there won't be any routing table entry for the global IPv6 addresses. Again, the local kernel will report failure without sending any packets.
if the system does have a global IP address, but some link necessary for routing is missing, the source should be getting an ICMPv6 error message, indicating that the destination cannot be reached; likewise if the destination has an IPv6 address, but the service isn't listening on it.
There are of course cases where things can break, e.g. if a global (or tunnel) address is configured, and something falsely filters out ICMPv6 error messages. You shouldn't worry about this case - it may be just as well that IPv4 connectivity is somehow broken.
Of course, it's debatable whether you really need to try the IPv6 addresses first - you might just as well try them second. In general, you should try addresses in the order in which they are returned from getaddrinfo. Today, systems support configuration options that let administators decide in what order addresses should be returned from getaddrinfo.
Subsequent to the question being asked the IETF has proposed an answer to this question with RFC6555, a.k.a. Happy Eyeballs.
The pertinent point being the client and server may both have IPv4 and IPv6 but a hop in between may not so it is impossible to reliably predict which path will work.
You should let the system-wide configuration decide thanks to getaddrinfo(). Just like Java does. Asking every single application to try to cater for every single possible IPv6 (mis)configuration is really not scalable! In case of a misconfiguration it is much more intuitive to the user if all or none applications break.
On the other hand you want to try to log annoying delays and time-outs profusely, so users can quickly identify what to blame. Just like every other delays ideally, including (very common) DNS time-outs.
This talk has the solution. To summarize;
Sometimes there are problems with either DNS lookups or the subsequent connection to the resolved address
You don't want to wait for connecting to an IPv6 address to timeout before connecting to the IPv4 address, or vice versa
You don't want to wait for a lookup for an AAAA record to timeout before looking for an A record or vice versa
You don't want to stall while waiting for both AAAA and A records before attempting to connect with whichever record you get back first.
The solution is to lookup AAAA and A records simultaneously and independently, and to connect independently to the resolved addresses. Use whatever connection succeeds first.
The easiest way to do this is to allow the networking API do it for you using connect-by-name networking APIs. For example, in Java:
InetSocketAddress socketAddress = new InetSocketAddress("www.example.com", 80);
SocketChannel channel = SocketChannel.open(socketAddress);
channel.write(buffer);
The slide notes say at this point:
Here we make an opaque object called an InetSocketAddress from a host
and port, and then when we open that SocketChannel, that can complete
under the covers, doing whatever is necessary, without the
application ever seeing an IP address.
Windows also has connect-by-name APIs. I don’t have code fragments for
those here.
Now, I’m not saying that all implementations of these APIs necessarily
do the right thing today, but if applications are using these APIs,
then the implementations can be improved over time.
The di!erence with getaddrinfo() and similar APIs is that they
fundamentally can’t be improved over time. The API definition is that
they return you a full list of addresses, so they have to wait until
they have that full list to give you. There’s no way getaddrinfo can
return you a partial list and then later give you some more.
Some ideas:
Allow the user to specify the preference on a per-site basis.
Try IPv4 first.
Attempt IPv6 in parallel upon the first connection.
On subsequent connections, use IPv6 if the connection was successful previously.
I say to try IPv4 first because that is the protocol which is better established and tested.

Resources