Finding ethernet addresses with a bash script - linux

I'm working on an assignment where I have to grab the ip addresses of the computers on a local network and attempt to discover the associated ethernet address using a script on linux.
I'm up to the point where my script gets all the addresses but I'm not sure how to get the ethernet addresses using that information. The assignment specification says that 'ip' and 'ping' may be helpful but I'm not sure how to use them to query the other computers for their ethernet address.
Any help would be appreciated.

To lookup MAC addresses you could try arp
/usr/sbin/arp
you may need to provide the explicit path to it if its in /usr/sbin unless you are running as root.

Depending on your permission on network you can use nmap ping scan:
nmap -sP 10.168.254.*
or
nmap -sP 10.168.254.0/24
Above command will scan all the host on the network 10.168.254.0 and will give you IP and MAC both.
This would work only for host which are up/visible and allow ping return.
And in your script you shall have to filter the output for mac-ip pair.
You can achieve many solution using nmap, this is the tool for you.

first you can ping an ip address then use arp -a

Related

Means to get IP and MAC information from a list of known Hostnames

I have a list of hostnames for mixed Linux distros (some Solaris, some RedHat, some Ubuntu), I need to get the IP and MAC for any Ethernet devices on each distro.
I don't have root access to any of these servers, so I wrote a bash script on one that remotely runs on the others and returns IP and MAC parsed from output of ifconfig. Because this script uses an expect file to pass in my password, it takes a long time to execute and is not very elegant.
There has to be a better way to do this. I know of a few tools that can do it for me but unfortunately I can't install any additional packages as I don't have permissions to do so.
The output of arp -a gives exactly what I want, but the problem with this is some of these entries seem to have multiple IPs and hostnames binded to the same MAC address. So I get entries like:
HOSTNAME-1 (IP-1) at SAME_MAC_ADDR [ether] on eth0
HOSTNAME-2 (IP-2) at SAME_MAC_ADDR [ether] on eth0
? (IP-2) at SAME_MAC_ADDR [ether] on eth0
Is there a way to firstly get all IPs and MAC addresses from the list of hostnames I have? I'm guessing arp is what I need here?
Secondly, is there a means to get all additional hostnames or IPs associated with each MAC address if there are duplicates?
The arp command will show the list of MAC address and associated IP addresses of hosts known to the one you are connecting to.
ifconfig is the right tool to use (or "ip a" in some distros). Why don't you try to put a cron job in every machine to store the result of "ip a" or "ifconfig" into a tempfile and instead or executing the command in every remote host, you just donwload this file and parse in your local server?
If not, they only way to get accurate information of network adapters in a *IX box is to get into the host and ask for this info.

Traceroute for MAC address

I'm having a problem in my network and I need to know with path the source and destination MAC address of the test environment are taking.
GNU/Linux has any command like this, similar to mtr or traceroute to MAC address?
Best regards.
No. You cannot ping or traceroute a MAC on another network segment.
MAC addresses are used on your local network, when you can just broadcast a message to all network devices. If routers comes into place you need some kind of hierarchy or routing information. So when sending from one network to another you need a protocol like for example IP.

Hostname discovery for all machines on a network

Problem: I am developing a graphical front end for a distributed CPU/GPU simulator. As this simulator utilizes MPI, it requires a hostfile detailing the hostnames for all computers being used on the network so that it knows what machines to distribute across. As the end users for my application are not computer scientists (and may not even be very computer literate), I can't expect them to know/find the hostnames of every computer on their network/cluster. I would like to programmatically perform this hostname discovery so that, upon application start-up, the user can see the available machines, and from those, pick the hosts they want to run on. If possible, I would like this solution to be cross platform but as the simulator currently contains some linux dependencies I can deal with a Linux only solution.
What I have tried so far: I tried utilizing the nmap package to discover hosts on a network with commands like nmap -sP <ip address range> using the ip address range for that local network. However, it only dumps the IP addresses for the hosts (not the host names) and I'm not sure how to translate these IP addresses into ssh hostnames (as MPI uses ssh for host discovery). Additionally, I used a similar approach with ping supplying the broadcast address and it returned nearly identical results.
I apologize for the broad nature of this question and the lack of code shown but I am not very experienced with network probing / programming and I am really not even sure where to start. I tried googling this but I was unable to find a suitable option (possibly because my lack of experience caused me to use improper terminology triggering improper results) My background is primarily in graphics and user interface programming, so this is a little beyond my comfort zone.
SSH doesn't care if it is given hostnames or IP addresses to connect to (not sure if this applies when there are host-specific configurations). Most MPI implementations don't care too, e.g. in Open MPI connection URIs addresses are all numeric, so a hostfile with IPs would be fine. HTTP servers on the other hand care because of the virtual hosting thing where many different sites resolve to the same IP address but the server is supplied the actual hostname via the Host HTTP header.
Unsolicited advice: finding hosts by ping is fine, but it doesn't guarantee that you have found machines, where SSH is running. You would better scan for systems with port 22 open that accept TCP connections:
$ nmap -oX -sT -p22 <ip range>
-oX produces XML output that can be easily parsed. -oG is also a nice format for automated parsing of the scan results. Also having SSH running doesn't necessarily mean that the user would be able to log into the system - for example it could be a network router or another remotely manageable device. One also has to take care of only showing machines where the user can log on without having to supply a password, e.g. with RSA/DSA public keys, otherwise starting an MPI job would be a really tedious task. You can test each host found with something like:
$ ssh -2 -o "PreferredAuthentications=gssapi-with-mic,hostbased,publickey" \
<host> hostname
This command basically excludes all interactive authentication methods. If connection succeeds, it will output the hostname of the remote machine. Otherwise you'd get a permission denied error and a non-zero exit code from the SSH client.

How to detect when known wireless devices join my wireless LAN on Linux

I am going to make mobile device detector using a single board computer (SBC) running a Linux based OS. The SBC will have a USB/802.11 wireless adaptor. The SBC will be a DHCP server. The mobile device will join the wireless network (adhoc or infrastructure, it doesn't matter) of the SBC. When the mobile device joins the network, the SBC will detect it. It will check the MAC address of the incoming mobile device with a set of accepted addresses. If there is a match, the SBC will execute a command.
I have basic Linux knowledge. I can't write shell scripts but I know C++/Qt. I don't know where to start. Do you know relevant command line utilities or libraries to use in this project?
P.S: Maybe I only need a way to detect when dhcp client list changes. Together with mac address filtering, this may work.
You can use nmap to discover your network. Here you can find some examples.
Then you should parse it's output. E.g.:
while true; do
nmap -v -sT 192.168.0.0/24 | fgrep "YOUR_SEARCHED_IP" && \
echo BINGO "YOUR_SEARCHED_IP" IS IN THE 192.168.0.0/24 NETWORK
done
And nmap has an -sn option to skip the port checks.
Even better you can use ip neighbor show to see your neighborhood networks IP address.
Or you can use a simple ping test, like:
for ip in $(seq 1 254); do
ping -c 1 192.168.1.$ip>/dev/null && \
echo “192.168.1.$ip is UP"
done
And you can combine it with nslookup to see the hostnames.
nmap tests the IP layer, but wireless devices are not required to use that.
You can also use "Monitor" mode on your wireless interface and/or combined with an appropriate listening program such as e.g. airodump-ng. Note that if the wireless network uses client isolation, you may see much less clients than are in fact participating, and also note that, just like properly-switched Ethernet, you won't necessarily see distant clients located in another segment.

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