SNMP payload address translation - linux

I'm using iptables under linux to NAT SNMP traffic. Some of the SNMP packets have VARBINDs that contain the (real) IP addresses of the devices that generated them. This confuses standard management tools, which need to see the NATted addresses in the VARBINDs. So I need to translate the addresses in the payload in addition to those in the headers.
The standard tool is the nf_nat_snmp_basic.ko kernel module, but the original version translates only the first octet of the address and the latest version simply corrupts the packets altogether. This is apparently "common knowledge" on the web (www.netfilter.org) and I've verified it on my own equipment.
Before I dive into the kernel, has anyone else worked on this problem and come up with a suitable solution? For now, it's sufficient to translate only those VARBINDs whose OIDs specify their type as an IP address. In other words, I don't need to translate addresses that are embedded in string data, which would be far more difficult.
Thanks for your suggestions!

Possible DIY solution from Robert Gamble here: Packet mangling utilities besides iptables?
Updates and more praise to come after a bit of unit testing -- thanks, Robert!

Related

Packet injection, filtering and mangling WITHOUT GPL?

I'll have to do packet inspection, mangling, dropping and injection of packets on a Linux system. Ideally, this would be in user space and on IP packets and Ethernet frames, too.
Unfortunately, I cannot go OpenSource for this which basically rules out any approach based on NFQUEUE and libnetfilter_queue, since all of netfilter (and their dog) is GPL only.
I thought about using TAP/TUN devices in parallel to controlling netfilter by simply calling iptables, but this seems to be messy at best...
So, are there any alternatives to netfilter?
I believe your issue is that libnetfilter is subject to the GPLv2 licence (not LGPL) and any project building on these would thus be subject to the GPLv2 licence too; this is what you want to avoid (I think).
An alternative would be to use a language binding which is not subject to the GPLv2 licence. One candidate would appear to be the Go bindings - see here for example, which appears to be under the Apache licence. I have obviously not checked the provenance of every file therein. Another way would be to divide your application into two - a small layer that communicates with Netfilter, communicating via (e.g.) an RPC interface with the rest of your application.
However, the last time I faced this, I used libpcap instead, which is BSD licensed. It's a little known fact that libpcap can send raw packets as well as receive them. However, it is much lower level than netfilter - you get raw packets and that's about it.
The license does not apply to your userspace application.

Determine whether MAC address is physical or virtual on Linux

I have tried using several commands as well as couple of examples using C/C++ but am still not able to find a flawless method that can differentiate between physical or virtual ethernet adapters. Physical means, on that available on your board or installed externally and virtual means created by virtualization apps such as VirtualBox/VMWare/Virtual PC or VPN etc.
Any pointers?
There is no flawless method. A virtual adapter can have any MAC address, including one that might have been assigned by a constructor to a physical device. And the other way around, given that one can change the MAC address of a physical adapter. You can only make an educated guess.
You might find it easier to detect if you are running virtualized at all, rather than look for specific information about the NICs. The virt-what(1) tool looks through aspects of the running system to guess if the system is virtualized or not. (The script isn't as smart as you think, but it does have a lot of small information gathering tools in one place.)
Someone intentionally trying to bypass a license check would probably not find it difficult to defeat this mechanism.
Maybe one can use mii-tool and check if it fails, which it does for virtual:
mii-tool vmbr2
SIOCGMIIPHY on 'vmbr2' failed: Operation not supported
mii-tool eno1
eno1: negotiated 1000baseT-FD flow-control, link ok
EDIT:
What is mii-tool: view, manipulate media-independent interface status
This utility checks or sets the status of a network interface's
Media Independent Interface (MII) unit. Most fast ethernet
adapters use an MII to autonegotiate link speed and duplex
setting.
https://www.man7.org/linux/man-pages/man8/mii-tool.8.html

What is the simplest way to get IP address of a domain?

We're developing an embedded application, running on a standalone GPRS connected device (no operating system there). We are trying to get an IP address of domain name. I think that we should use some public DNS service, like Google DNS (8.8.8.8). The question is - what is the simplest request we should send to 8.8.8.8:53 in order to receive IP address of our domain?
Again, we can't use libresolve or any other similar libraries. We will make a simple TCP connection to port 53 of Google DNS, and will format our request ourselves.
I tried to understand RFC1053 myself, but failed. Too many words :)
I'm not a DNS expert in any way, but I thought that DNS generally use UDP rather than TCP?
Either way, here's a link to a page that describes the communication using less words that might be easier to understand than the RFC itself.
Also, even if you can't use the libresolve library itself, can't you look at an open source version of that library and use the code from one of those (assuming that the license is compatible with your work). Here's one from Apple that I found via google.

Is ARP source hardware address redundant?

I'm working on a network security project and I noticed something that I can't explain:
Why do we need a source hardware address field in arp? Isn't it already contained in the ethernet header?
ARP is designed this way so that it can run over other hardware, not just Ethernet. Have a look here.

Doing ARP and Inverse ARP on Linux 2.6.21 (glibc 2.3.5)

I need to store persistent reference to third party device on an arbitrary IP network where the IP address of the devices may be static or randomly assigned by DHCP. I don't control the devices on the network and I can't rely on DNS and other ad-hoc networking protocols existing or working with the devices.
So I have been instructed to investigate using hardware addresses and ARP. This will work but I don't want to duplicate code. The kernel must manage an ARP table. On Windows you can access it using GetIpNetTable etc.
I am hoping there is an API to answer these two questions:
How do I translate from IP to MAC address? (ARP)
How do I translate from MAC to IP address? (InARP)
If not then I may have to do it more manually:
How do I read the kernel's ARP table?
How do I add an entry if I have the determined a mapping myself?
/proc/net/arp
K
ARP tables tend to be fairly local and short-lived. If you examine the protocol, the real MAC addresses are generally only provided when the given IP address is in the local subnet.
Otherwise, the packet is forwarded to the local router, which is then responsible for forwarding it.
If you do "arp -g" on Windows or "arp -a" on UNIX, you'll see the table, but I don't think it will do you any good, due to the reasons mentioned above. That command and
That's really what DNS is for but, as you say, it may not be an option for you.
You may well have to write your own 'ARP' database at your application level.
As for ARP:
You could use system("/usr/bin/arp -option_of_choice"); and parse the output, but that's an ugly hack. -- Not my recommendation.
Take a look at /usr/include/linux/sockios.h -- At the SIOCGARP, SIOCDARP, and SIOCSARP details. Those are ioctls that you can perform to manage the ARP table on linux. Of course, you'll have to perform these ioctls on a socket fd.
Here's some examples: SIOCGARP examples
I'm sure you can find many other examples in several other languages as well. As I'm assuming that you're using C.
As for RARP:
A quote from the linux rarp manpage:
" This program is obsolete. From version 2.3, the Linux kernel no longer
contains RARP support. For a replacement RARP daemon, see ftp://ftp.demen-
tia.org/pub/net-tools"
So you'll have to install rarpd on the target system.

Resources