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

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.

Related

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

On Linux: how can I programmatically determine if a NIC interface is enabled and plugged in?

I want to determine if a network card is enabled, up, and plugged in. Basically, I want to know if the network card will work. I need this information from with a C++ program, and would like to display an error message when the network isn't working properly. If possible I would like to avoid using shell commands to determine this information.
You can look at /sys/class/net/eth0/operstate where eth0 is your interface to see if it's up.
Look at /sys/class/net/eth0/carrier to see if there is a carrier.
Though I guess executing ifconfig and friends will give you more compatibility to *BSDs.
open AF_NETLINK socket
bind it to sockaddr_nl with nl_groups = RTMGRP_LINK
send message RTM_GETLINK to kernel
make poll/epoll on socket to read RTM_NEWLINK and RTM_DELLINK messages
you will receive initial interfaces list and its changes in future
Remember, on Linux "everything" is a file.
The best way would be to use the approved kernel<->userspace communication, namely sysfs, mounted at /sys. Network devices are linked at /sys/class/net
If you wish to use the ioctl interface, look at man netdevice
How do you want to identify the network card? You might try taking a look at /etc/udev/rules.d/70-persistent-net.rules which maps hardware MAC addresses into nice names (like eth0).
Then, when you have the nicer name, you can run things like ethtool eth0 to determine if it is [physically] connected (last line), ifconfig eth0 to determine if it is up (look for "UP BROADCAST..."), and if it has an IP address.
I'm willing to guess there are automatic libraries for this though; have you looked around? I'm not sure if there's easily accessible code in NetworkManager, but that should be a good first place to look.
Run through the output of getifaddrs, you can use the link layer for the MAC address to identify an adapter and check the ifa_flags for IFF_UP. Use AF_NETLINK for notifications about interface changes.

Implementations of Mobile IP on linux

Are there any standard implementations of Mobile IP for Linux?
If I want to support mobile IP for a network, what all needs to be done?
If I have to write code from scratch, is it likely that a kernel module will suffice or I would have to make changes to the kernel code.
I just need a bit of headstart to know where to begin.
It appears likely to me that it can be done without requiring any kernel code at all, you can achieve it by having a userspace daemon create a tun interface (much like a VPN client would typically do) and then route or encapsulate packets in whatever way is required for mobile IP. The userspace daemon may have to modify the kernel's routing table but that's ok.
Examples of the tun interface users are openvpn and Qemu.

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.

SNMP payload address translation

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!

Resources