I have a device that is made up of separate modules running embedded linux. The modules are all the same hardware and software but perform different tasks depending upon their location in the device. All the modules talk to each other over an internal network. The ip addresses of the modules are set statically based on the location in the device. This is done by having the modules read a physically set device that returns a 0-15 number. It plugs into the modules but is physically attached to the location in the device. A device might have 6 racks, so there are 6 of these plugs set 1-6.
I want the device to determine if any module is incorrectly set as this would cause two or more modules to have the same IP address. This could be caused by either an incorrectly set or broken location dongle. The modules communicate with each other using broadcast UDP messages. One of the data members of the message is a unique 48-bit serial number, the MAC address.
My initial plan was to have all the modules compare the messages that are from themselves with their serial number and throw an error if they don't match. The problem is the modules only receive the broadcast packets that are either from themselves or another IP address. They are not seeing packets that are from the same IP address but a different module.
When I check the interface using ifconfig I can see the Rx packets increasing, but when I use netstat -su I see nothing. The UDP Rx packets never increment. Therefore, at some point they're being dropped from the stack.
Is there a way around this? I know I can rely on a third node to tell it is receiving broadcast packets from the same IP address but different MACs, but I was hoping have each module be self aware of this problem.
Upon startup the modules should broadcast an ARP packet annoncing their MAC and IP. This is the 'normal' solution for duplicate IP addresses, you could listen to these broadcasts and send one new one, this way your modules will detect someone else on the network is using the same IP.
Related
I am trying to find out whether the machines in a network are running a certain app. More like, I am trying to resolve addresses of nodes in a network.
I built a small code based on ARP, but it works only on a local network(same subnet). What I want to do is resolve addresses out of the subnet i.e. all other nodes.
I read these answers: UDP broadcast packets across subnets
and Broadcast on different subnets
But they all talk about changing router setting or creating a multicast network.
From what I read for multicasting to work, I need to create a multitask network beforehand. Is it really necessary?
And for changing router setting, does it really have to be a "special" router?
This is all for a college assignment and would be demonstrating it probably on an ad-hoc network or something like that.
I am open to ideas to solve the original problem.
PS:
1. I am a beginner in networking so do excuse me for any fault or misinterpretation.
I am using sockets and C(No other option).
Edit 1:
I am well aware ARP is useless outside the subnet. I mentioned it because I used it and it helped explaining the problem.
Edit 2:
The original problem is:
Building a chat application, nothing fancy sending messages from one point to another, without using a central server of any kind. Not even a hybrid network with a central store is allowed.
i.e. if A and B are two clients, A should directly connect to B and vice versa.
I did some research and decided to use P2P architecture. And now I am stuck to how will A discover address of B. If I know the subnet of B, I can brute force and locate B but since I don't have such information what do I do?
ARP is not intended to be routed outside the local network, where in IPv4, the "local network" typically corresponds to a subnet. You should not expect ARP traffic to transit routers from inside to outside or vise versa.
Similarly, UDP broadcasts generally do not propagate outside the local network, and it's a good thing that they don't, for reasons related to both security and traffic volume.
From what I read for multicasting to work, I need to create a multitask network beforehand. Is it really necessary?
Basically, yes. Your routers need to be configured to support multicasting (which may be their default). All participants need to agree on and join the same multicast group. There might not be a need for any new networking hardware, but multicast communication has its own protocols and network requirements; it is not merely a broadcast that can traverse network boundaries.
And for changing router setting, does it really have to be a "special" router?
If you mean changing router settings so that UDP broadcasts are routed between networks, you do indeed need a router that exposes this capability. But I urge you not to do this, as it will let broadcasts from all other sources, for all other reasons transit the router, too. At minimum, this will significantly increase the noisiness of all networks involved, but it could produce bona fide misbehavior of applications and services other than yours.
The Limited Broadcast (255.255.255.255, which is used by ARP requests as the destination address, and ARP only works for IPv4 on the local LAN) cannot cross a router, and a Network Broadcast (last network address, where the host is all ones) by default cannot cross a router (Directed Broadcast) because it is a security risk (see RFC 2644, Changing the Default for Directed Broadcasts in Routers).
Some routers can be configured to forward directed broadcasts, but this can be dangerous.
Multicast is a form of broadcast. Multicast routing is very different than unicast routing, and every router in a path must be configured for multicast routing. Also, hosts must subscribe to a multicast group before they will even listen for packets from a multicast group. Additionally, there are some multicast groups that all hosts listen for, but those are link-local multicasts that cannot be forwarded off the local LAN.
Adding to what other answers have provided:
ARP is not useful for a system in another subnet. Even if you were able to send an ARP request to a system in the other subnet, and receive its response somehow -- providing you with that system's MAC address -- you could not use it to send a packet to that system because Ethernet does not provide a routing mechanism, and so the system will never see any Ethernet packet you address to it.
If you are simply trying to identify which systems within another IP subnet are live, you can probably do this by other means. Take a look at the nmap command, for example. It supports a wide variety of IP communications methods that will be routed to the other subnet and can often detect what machines are present and which services are available on the machines found.
And you can of course duplicate what nmap does yourself. For example, if you want to find out which systems in subnet 192.168.10.0/24 are listening on TCP port 80, one way is to simply attempt to connect to port 80 on each system in that subnet. In general, there are four answers you may receive back:
Connection success (No error: the machine is present and there is a program listening to that port)
Connection refused (errno ECONNREFUSED: the machine is present but there
is no program listening to that port)
No route to host (EHOSTUNREACH: there is no machine answering to
that IP address)
No response (ETIMEDOUT: several reasons why this can happen; for example, the system could have firewall settings causing it to simply ignore the request)
(And there are other less likely possibilities as well.) Using other IP access methods (ICMP/ping, UDP packets) will have a different matrix of possible results.
As others have explained, multicast mechanisms would only be helpful for discovering a set of cooperating machines that are pre-configured to join a multicast group.
I know one IP address of the remote node via. traceroute. However, I want to know all the IP address in its interfaces. How can I do so? The node doesn't have hostname so I can't use the API to get various ifaddress using hostname API. I searched various places but couldn't find on how to get the various IP address of the remote node. Is it possible to get it? Basically, I am implementing traceroute and my aim here is to display the loopback address of the intermediate node and not the actual interface address. In case loopback address is not available, I would like to display the actual interface address. I am struggling here and have no clue on it. This is all implemented using C - linux, UDP socket.
I want to know all the IP address in its interfaces. How can I do so
Lookup DNS or login in and use the OS dependant tools/APIs to lookup the local interfaces' IP addresses, else you are lost.
Technically if you are on the same network you could use the macid, and sniffing network traffic, to find other IPs on that interface, but once you leave your local network, its near impossible to find out other ips that machine is listening to, this would be a security issue if they made this information available.
The way traceroute works is by sending packets with increasing IP TTL values towards a remote address and the routers along the way will generate back ICMP TTL time exceeded thus revealing their IP source address back to the sender and so you get to know the hops that your data might be traversing when attempting to communicate to a specific remote address. The icmp error message will contain the ip address of the hop's incoming interface and in your case you want to discover also all other ip addresses assigned to further outgoing interfaces (outgoing as seen from your sender perspective) but this is not possible by using the above mentioned technique or any other.
I want to be able to simulate an incoming packet on a certain physical network interface.
Specifically, given an array of bytes and an interface name, I want to be able to make that interface think a packet containing those bytes arrived from another interface (most likely on another machine).
I've implemented the code that prepares the packet, but I'm unsure what the next step is.
I should point out that I actually need to feed the interface with my bytes, and not use a workaround that might produce a similar results in other machines (I've seen answers to other questions mentioning the loopback interface and external tools). This code is supposed to simulate traffic on a machine that's expecting to receive traffic from certain sources via specific interfaces. Anything else will be ignored by the machine.
I'm going to stick my neck out and say this is not possible without kernel modifications, and possibly driver modifications. Note that:
There are plenty of ways of generating egress packets through a particular interface, including libpcap. But you want to generate ingress packets.
There are plenty of ways of generating ingress packets that are not through a physical interface - this is what tap/tun devices are for.
If you modify the kernel to allow direct injection of packets into a device's receive queue, that may have unexpected effects, and is still not going to be an accurate simulation of the packets arriving in hardware (e.g. they will not be constrained to the same MTU etc). Perhaps you can build an iptables extension that fools the kernel into thinking the packet came from a different interface; I'm not sure that will do what you need though.
If all you need is simulation (and you are happy with a complete simulation), build a tap/tun driver, and rename the tap interface to eth0 or similar.
Depending on which network layer you're trying to simulate, there may be a work-around.
I have had success getting ip packets into the ingress queue with an ethernet 'hairpin'. That is, by setting the source and destination MAC address to the local interface, sending the packet results in it first appearing as an egress packet, then being 'hairpinned' and also appearing as an ingress packet.
This at least works under linux using pcapplusplus (libpcap under the hood), with my wireless interface. Your millage may vary.
This will obviously only suit your needs if you're OK with modifying the ethernet header, ie only simulating a higher layer.
Here is a snippet of c++ where I spoof a rst tcp packet for a local socket:
//always use the actual device source MAC, even if we're spoofing the remote rst
// this produces a 'hairpin' from the egress to the ingress on the interface so the tcp stack actually processes the packet
// required because the tcp stack doesn't process egress packets (at least on a linux wireless interface)
pcpp::EthLayer eth(localMAC,localMAC);
pcpp::IPv4Layer ip(remoteIP, localIP);
pcpp::TcpLayer tcp(remotePort, localPort);
pcpp::Packet pac(60);
ip.getIPv4Header()->timeToLive = 255;
tcp.getTcpHeader()->rstFlag = 1;
tcp.getTcpHeader()->ackFlag = 1;
tcp.getTcpHeader()->ackNumber = pcpp::hostToNet32(src.Ack);
tcp.getTcpHeader()->sequenceNumber = pcpp::hostToNet32(src.Seq);
pac.addLayer(ð);
pac.addLayer(&ip);
pac.addLayer(&tcp);
pac.computeCalculateFields();
dev->sendPacket(&pac);
EDIT: the same code works on windows on an ethernet interface. It doesn't seem to do the same 'hairpin' judging from wireshark, but the tcp stack does process the packets.
Another solution is to create a new dummy network device driver, which will have the same functionality as the loopback interface (i.e. it will be dummy). After that you can wrap up a creation of simple tcp packet and specify in the source and destination addresses the addresses of the two network devices.
It sounds a little hard but it's worth trying - you'll learn a lot for the networking and tcp/ip stack in linux.
Using C I am trying to discover the IP of a locally connected device without knowing any information about the device.
[ my box ]--eth0--------------[ unknown device ]
I can't seem to find a way to arp/broadcast to get the IP of the device. I understand that if I use multicast the device itself has to be a member of the group. When I arp or arp-scan they ask me to assign my eth0 interface an IP but I don't have one assigned, I can put one if I need to but I am unsure what it needs to be set to in order to discover anything.
Example: I have a Linksys wireless IP camera and I want to find the IP/Subnet. Without knowing its subnet/netmask I wouldn't know what to set my eth0 to.
I have written a C program to parse the arp table in Linux but I cannot seem to get the IP from the locally connected device in it. As mentioned above, I cannot use these tools without setting eth0 to something.
I think Your best chance to find something is by capturing all incoming network traffic, especially while unknown device is booting (using tcpdump, wireshark or something similar). Just filter out traffic, which is sent from my box.
Most likely You'll see DHCP requests and maybe ARP requests. If device is using DHCP, the easyest solution would be to run DHCP server on eth0 (so You can assign IP to this device).
If for some reason You need to program in C (and network capture gives expected results), libpcap may be usefull.
If evrything else fails, You can try to dicover unknown IP using fake ARP packets (so You don't need to change IP on eth0) and capturing any responses.
If I use arp and arping on machines in my local network I get the mac addresses from them. In the same way I can construct and send a ARP request and collect the response to these machines. This is used since I build raw packets completely from scratchy (to allow spoofing of every possible field, including mac addresses if needed). But, when I try arping or arp on external ip's and hosts such as google.com it doesn't get any reply. What should the destination mac address be set to when sending packets to targets outside my local network? I guess the router since that's what passes it on... am I correct? Is there a quick way in ANSI C to collect the mac address of the router in use by the computer? Or at least the IP so I can send a ARP request to it.
Thanx in advance
MAC operations are limited to machines directly connected within your subnet. So you should use the router's MAC address for packets intended for hosts outside your subnet.
There are numerous ways to obtain the router's IP address.
You can parse the configuration files on your local host if the interface is statically configured.
You can see if your compute platform has an API that lets you access the interface configuration information directly. This would work in both static and dhcp cases.
You can write socket code to send an ICMP message to an outside address then parse the incoming responses. They will be from the router. The stack will, in this case, find the router for you.
It should be set to the gateway (assuming ethernet on that link...).