Sending ARP reply with arbitrary source MAC - c

This is a follow-up to my previous question: ARP reply packet does not update ARP cache on Ubuntu. It turned out that my problem was that I was using an arbitrary MAC address as my source MAC (ie. one that doesn't exist on my network, say aa:bb:cc:dd:ee:ff). I could send ARP replies to poison my cache with no problem as long as my source MAC matches with the MAC of my NIC. I tried to manually set my NIC to have an arbitrary MAC address, then send ARP replies using that as my ARP packet's source MAC - also worked.
I am wondering if anybody knows the inner workings of this. Was there some kind of check that prevents packets with mismatched source MAC from being sent? Was it a check between the source MAC of the Ethernet frame vs. the source MAC of the ARP packet? And for the purpose of an experiment that I'm running, is there a way to bypass this restriction?
JY

Various optimizations are possible to make ARP work more efficiently.
To start with, once a machine has run ARP, it caches the result in
case it needs to contact the same machine shortly. Next time it will
find the mapping it its own cache, thus eliminating the need for a
second broadcast. In many cases, host 2(receiver) will need to send
back a reply, forcing it, too, to run ARP to determine the sender's
Ethernet address. This ARP broadcast can be avoided by having sender
include its IP-to-Ethernet mapping in the ARP packet.
Quoted from Tanenbaum's Computer Networks, fifth Edition p486-487
So it looks like your receiver fails to resolve MAC of the sender. And Tanenbaum presented a solution to you to avoid this failure.

Was there some kind of check that prevents packets with mismatched
source MAC from being sent? Was it a check between the source MAC of
the Ethernet frame vs. the source MAC of the ARP packet?
You mention Ubuntu. In Linux, you can send any Ethernet frame (see examples), so internally there is no any kind of such check. But you did not tell how do you attempt to send the spoofed ARP messages; maybe the way you are doing it is limiting your options for the source MAC address.

Related

Find the next hop MAC address for ethernet header

I want to send a packet to another machine but with a different MAC address in the ethernet header. For this I am using raw sockets in C and creating my own ethernet header so that I can set the source MAC as desired. The trouble is that I am not sure what destination MAC address to fill in the header. I know the IP of the destination machine but not the MAC. Even if I knew, I don't want to hardcode this MAC.
One option I see is that my machine would know the MAC in its ARP table and I could read it and get the MAC address and fill it in. But doing this before sending each packet is overhead. I could read it once and keep using but what if some day the destination machine gets replaced. The admin would assign the same IP address to the new machine but the MAC address would be different. Probably when the new machine boots up, it would send a Gratuitous ARP and my machine would update its ARP table. But my program wouldn't know this. My program would keep sending packets with old MAC.
I feel I am missing something very basic. Thoughts?
What you are seeing here is the same problem that everyone faces, who tries to implement a network stack.
You have several options:
If the packet is a reply packet, then just use the MAC address of the from address
You can maintain an own arp-table and send a arp request if the entry in your table is missing or outdated. Parse arp replies and update your table accordingly. Packets to be sent without a valid arp table entry have to be queued. This is the most elegant, but also a very demanding option.
You can simply send the packet to the MAC of your local router. It will forward the packet to the correct host specified in the IP header. If your local router employs protocols like vrrp, hsrp or gblp, then the MAC address is always the same and doesn't change, even if your router is replaced.
You can read the MAC address from /proc/net/arp or with ioctl(SIOCGARP, ...);, but the entry for the IP you are looking for might not be present, if your host hasn't tried to communicate with it recently. You could, of course, send a dummy packet with sendto(); to that host before reading the arp table.
If you describe in more detail what you are planning to do, the suggestions might get better.
You can set the MAC address for the device with SIOCSIFHWADDR ioctl request. The manual for netdevice is a good starting point for this.

ARP reply packet does not update ARP cache on Ubuntu

So after I have played with the Network Spoofer developed by Digitalsquid (http://digitalsquid.co.uk/netspoof/), I have been trying to get a better understanding of its internal working by writing a c program that does something similar.
My program currently takes in 4 parameters - source ip, source mac, victim ip, and victim mac - and send an ARP reply packet with them. When testing the program on my home network, I would do something like setting the source ip to be the router's ip, source mac to be something bogus, victim ip to be my laptop's ip, and victim mac to be my laptop's wireless card mac.
The problem is, although I can see the packet being sent/received from monitoring the wireless card using tcpdump (ie. I would see something like "01:43:23.656745 ARP, Ethernet (len 6), IPv4 (len 4), Reply rouer-ip is-at bogus-mac-address, length 28", which is just what I expected), the ARP cache entry for the router stays the same (ie. still has the correct mac address).
I am not quite sure what the problem here is, and why I couldn't poison my ARP cache. I read somewhere that it could be my OS, Ubuntu 12.04, dropping the unsolicited ARP packets, so I tried to set /proc/sys/net/ipv4/conf/wlan0/arp_accept to 1 - no luck. I also tried to turn IP forwarding on (setting /proc/sys/net/ipv4/ip_forward to 1) as suggested by another article, and still had no luck.
I would really appreciate if somebody can give me some pointers/hints as to what the problem might be. Also, please correct me if I had a mistake in my understanding - I am quite new in the realm of c programming and ARP spoofing.
Thanks!
JY
Its good to take these arguments(source ip,source mac,target ip and target mac),but you are not giving correct values to it.
suppose A=the victim
and B=Gateway/Router/Switch in your network
ARP spoofing is actually convincing both A and B
You need to be more active in sending ARP request/reply to both A and B by giving your MAC address to be desired node.
So that whatever A/B sends will come to you first.
IP and MAC address fields are basically updated in CAT(content Addressable Memory) table of switch which keeps on updating time to time.
So when you are sending ARP Reuest to A(i.e Router/Gateway/Switch):-
Source IP=Victim's IP i.e A
Source MAc=your MAC(hackers MAC) so that data may come to your system
Destination IP=Rouer's IP
Detination MAC will be blank in case of ARP request

How can I extract mac address from a icmp reply in c on linux

I am trying to find out mac address of a machine in a switched environment after sending it a raw packet. I am trying to implement traceroute command . I want to know when i receive a ICMP time exceeded message how can I extract the mac address of that machine . I am a new to network programming so am confused what socket call will help me to extract the mac address.
Thanks .
No, you can not extract MAC address from ICMP reply.
You can only determine MAC addresses of linked machines next to you. In ICMP(tracert) you can just find out the IP address of target or middle machine.
If you want to detect MAC addresses, you should use ARP protcols where it's applicable in local networks not Internet.
ICMP protocol starts after IPv4 header[1] and MAC addresses is related to physical/link layer. In low level layers the MAC addresses will transparent from top level layers such as network(IP) or Transmission,...
To determining MAC addresses, you should use Raw sockets or PCAP SDKs to access lower layers of network programming. (I say again, these are not useful over Internet)
Like Masoud M said, you can only get the MAC address of machines that are on your local network. That said, you can parse the output the arp command to find the MAC address given the IP address of a machine one your local network.
In general, on internet, you don't even know the media a host is using for transmitting packets. Let's suppose a remote host is conected over a serial rs-232-C link with PPP protocol. It doesn't have a mac address. This also happens for example if the host uses a token ring interface or frame relay link. This makes determining the remote mac addresses of hosts a local issue completely. Normally, when you get a packet from a remote site over ethernet, the source mac addres you get in the packet is the one of the last router that links you to the internet, not the one of the original host that sent the IP packet. In the RFC on IP over avian carriers (rfc1149, rfc2549 and rfc6214) the media used for transmission doesn't allow to use mac addresses (the link address, if somewhat feasible on a pidgeon could be, would be its name)
If you want to read about traceroute on ethernet network of switches, perhaps you had to have a look at the IEEE802.1ag, that has an specification to do tracerouting over switches (tracelink service) but I think is far over the scope of this answer.

Is there a way to get destination mac addres in ANSI C

Is there a way to get the destination MAC address, if the destination IP is known, using ANSI C? I would preferably do it with a system call so the kernel deals with it all and I can take advantage of the ARP cache. I know I can build and send my own ARP request, but then I would not have the caching functionality etc unless I implement it myself so it feels like letting the kernel handling it is the way to go.
Not an exact answer, because it's not ANSI C, but you can read the arp table from /proc/net/arp (in Linux, that is). That's where arp looks. For any other OS, the easiest way is to use strace or an equivalent on the equivalent arp-cache-showing utility.
What I decided to do was to send my own ARP packets and caching it internaly in my application. If the destination is outside my local network I parse /proc/net/route and extract the gateway for the given interface and send an arp packet to the gateway to get it's macaddress (since that is the destination macaddress of packets destined outside the local network).

Programmatic use of ARP

I have a need for some C or C++ code, compilable under Linux, to be able to take a list of IP addresses of some arbitrary number of remote hosts machines and obtain a ethernet MAC address for each one. These host machines may be on the same subnet or they could be on a different subnet behind a router. Its OK if the MAC address of some or all of the remote hosts is the address of the interface on the router. Ultimately, I want to hand off the IP address and MAC address to an FPGA who will use these pieces of information to format and send UDP/IP packets over ethernet to the hosts. Obviously, the FPGA will also be given its own MAC address and IP address to fill in the source MAC and source IP addresses in the packets.
Is there some code I can be pointed to that can create and broadcast ARP packets to these remote machines and receive back the ARP response packets such that the destination MAC addresses can be extracted?
Part of what you want to do requires some raw socket programming.
http://mixter.void.ru/rawip.html
The source for the linux arp command will give the rest of what you need. Here's a link:
http://www.comp.nus.edu.sg/~cs4236/readings/out/html/arp_8c-source.html
I recommend looking into arping which is doing a somewhat identical job. It takes IPs and MACs and tries to receive additional informationen. Or justs pings them.
http://freshmeat.net/projects/arping/

Resources