I am writing a discovery program, written in C++ that will run on linux, to enable me to determine if certain devices are connected to the network. I have the Mac Address of the other devices and I need to resolve their Ip Addresses.
I have checked /proc/net/arp and the devices don't appear.
I tried pinging the broadcast address and this doesn't reach the target and therefore the ARP cache is not updated. However, if I ping the ip address directly it is (but this is not an option).
Also, the devices can be configured with either static ips or can get them via dhcp.
Is there any way that I can determine the ip addresses given the Mac addresses?
Some years ago I'd have suggested to use RARP but it is not supported by Linux kernel any more. Unless there is already a solution I would suggest you the following home-made solution:
-You can use Packet sockets to implement your own Layer 2 protocol: instead of using IP as payload of the Ethernet frame you can select your own protocol code (for example: instead of 0x0800 for IP use 0xABAB, always a number greater than 1536)
-In each node you implement a simple server that use packet socket to read the frames with that protocol code or you could use pcap, as you prefer.
-Whenever you need the IP address of another node you send an Ethernet frame to that MAC address. The server will read the new frame and respond with another frame conveying its own IP address.
-If you choose this solution please remember the payload has to be at least 46 Bytes long, so you may need to use padding. Also you can use the TLV (type length value) format for your own protocol.
Read this:
http://en.wikipedia.org/wiki/Ethernet_frame
http://man7.org/linux/man-pages/man7/packet.7.html
I hope this helps.
Related
When we send data to some server on the Internet, we specify its IP and port. If this server, for example, is written in C++, then sockets will be used on the server. But how does it work if we use Ethernet instead of the Internet? How can one computer understand that another computer sent data to it inside the ethernet network? Indeed, in this case, we do not use the IP and port to send data to the recipient, only the MAC address. How can you write a C++ program that "listens" to a MAC address and a client that can send data to the MAC address in C++? I don't fully understand Ethernet use cases in real world
Ethernet headers have an Ethertype field that tells ethernet to which process it should send the frame payload. You will need to establish a process and register an Ethertype number in the OS for that process in order to receive the payload of the frames with the Ethertype you are using.
You cannot just randomly choose an Ethertype number. You either reserve one with the IEEE, or you use one in an experimental range, e.g. 0x0101 to 0x01FF. There are several lists of currently reserved Ethertypes. IANA has Ethertypes, and it has information and links on how to reserve an Ethertype number and other lists.
Also, remember that you will not be able to use IP or any of the standard protocols (transport or application) above IP that depend on IP unless you write your own. Transport protocols, such as TCP in your OS, need IP for the required pseudo-header. You will need to write custom transport-layer protocol(s), applications, and application-layer protocol(s) that you may require to use your new custom protocol using your Ethertype.
Existing transport protocols, e.g. TCP, will not use your custom Ethertype protocol, and any existing application that use existing transport-layer protocols will also not work with your custom protocol.
Hello Stackoverflow experts,
I have been struggling with how to use the ip fragmentation provided by DPDK. and was wondering I have the correct concept of IP address and the MAC address used in rte-mbuf ethernet header.
Is Ip address alone in the header of rte-mbuf can be used to transfer from local to remote?
I see in the DPDK sample applications that the ip address is used in the hashed tables such as IP fragment table after the packets are received, but the fact that data is actually received just by using ethernet mac address, gives me the impression that IP address is only defined by the DPDK user (developers using DPDK API) and not used in actual data transfer.
Is there something missing to what I understand?
You are right. Most DPDK examples work on the second level of the OSI model, i.e. they only care about MAC addresses, not IP.
The IP reassembly example is based on L2 forwarding example, i.e. it acts as an Ethernet bridge. Though, it requires IP addresses to be analyzed, i.e. source and destination IPs must match for all the fragments of the same flow.
Now answering your questions:
Is Ip address alone in the header of rte-mbuf can be used to transfer from local to remote?
If you mean transfer using rte_eth_tx_burst() then no, IP header is not enough. The ethernet header must be filled properly as well.
IP address is only defined by the DPDK user (developers using DPDK API) and not used in actual data transfer.
Since the reassembly example is based on L2 forwarding example, it acts as reassembling Ethernet bridge. So you have a right impression, this example does not route packets based on IP addresses. It just uses IP addresses to reassemble IP fragments.
I'm trying to write a function that can get me the IP adress (and the name of the device as bonus) of devices that are in my network, the network is gonna be a direct connection between two computers using Ethernet cable or creating an access point (using wi-fi)
I tried to search about how to do it but it seems like I need to listen to the network or something which seems to be difficult.
hope you can guide me to what I should do or read to get started.
Note: I'm using Windows on both computers.
Edited:
P.S: I need the IP Address so I can send a message to the other computer using winsock in a Client/Server program I wrote.
can't I make the server send its IP to the client or the opposite ?
If your software is running on both machines, you can have one (or both) machines send out a particular broadcast (or, if you prefer, multicast) UDP packet on a specific port. Your program should also be listening on that same port. When it receives that packet (using recvfrom()), recvfrom()'s fifth argument will contain the IP address of the machine that sent the packet, i.e. the IP address you want.
(If OTOH your software is not running on the remote machine, you'll need to use some more general-purpose discovery mechanism such as mDNS or LLDP -- hopefully you won't have to do that, though, as it's a good deal more complicated)
I would like to time how quickly the latency is of a system by sending a packet with the same dest IP as the source IP. Is this relatively simple to do?
How would you custom-build the packets?
Would setting the two IP addresses achieve what I am after?
What is the best timing method?
Any tips/ideas at a low/high level would be greatly appreciated. I intend to use C/C++ on Unix with the boost libraries and libpcap.
EDIT: I should add I will be doing this on a home network, behind a router. I presume the packet will go to the router and come straight back if I were to use 192.168.2.1 (local IP of my system) for the source and dest addresses.
You can just try ping to your own IP. this will produce ICMP packets. There are libraries which also allows you to do the same from an application.
If you want to create packets for yourself you can use socket API. Remember, you can send the source IP address and destination IP address as same, but the port number needs to be different.
For timing you need can use gettimeofday function.
EDIT:
you can ping from your C++ program. See: http://verplant.org/liboping/ or check out some other forum. The reason i emphasized on ping is because it returns right back from the network stack. If you send a UDP packet on the other hand, expecting the application to return and echo, then the processing time of the packet on the listening server gets added.
If you ping to local machine ip (or even lo) it returns without going to switch or next hop router. It will respond even if you remove your eth cable or wifi.
What you are trying to do is implemented in NTP daemon with NTP protocol though.
You don't need a custom package for this. Just create a socket connecting to the same ip-address as the server, and start sending packages. Note that these packages will never leave the network stack, so what you will be measuring is basically how quick the system copies data between user-space and kernel-space.
For the timing, you can use the clock function, it's probably the one most widely used for such things.
I am using the Microsoft code here to learn how to detect IP addresses of cards and devices:
http://msdn.microsoft.com/en-us/library/aa365949%28v=VS.85%29.aspx
I notice some strange behavior.
I have a system with two ethernet cards; one is connected to the internet and one is connected to an ethernet device. When I run the sample code, it will always give an IP address for the card that has the internet connection, but the other card will come up as 127.0.0.1 with a subnet mask of 255.0.0.0 unless I have the ethernet device plugged in and powered. But the card should have a default IP address whether its actually connected to anything, right? How can I modify this code to detect that?
There's a third IP address detected that appears to be just empty data. I tried this on another computer with a single network connection and it also detected a second, non-existent connection. Each time, this connection has an IP address of 127.0.0.1 and a subnet mask of 255.0.0.0. What does this represent?
Given the demo code, would this be easy to edit to be able to detect IP addresses of devices on the network that any card is connected to? I really just want to detect the IP address that a single ethernet device is set to. The device is directly connected to the card. The reason I want to do this is because the device and card obviously don't play nice when their subnets are different and I want to detect when this is the case.
Thanks!
R
That address of 127.0.0.1 is not the address of the other card. It is the address of the loopback adapter - a virtual IP address that can only send and receive data with itself. The other NIC (that isn't plugged into a network) is simply not in the address table.
You may just want to call GetAdapterAddresses and filter out all adapters with an IFType of IF_TYPE_SOFTWARE_LOOPBACK.
If you want to see use existing tools that provide the same thing, type either of the following from a command prompt:
route print
(This will dump the routing table)
ipconfig /all
(this will show you the state of ALL adapters including the loopback)
Dunno exactly, you should at least specify your configuration, is it DHCP or static IP, or something else?
It's the loopback interface
Some broadcasting may be required. ARP is the link-layer protocol, so it can be used without the IP address to broadcast a link to find the devices and then to detect their address. Don't know about windows precisely, but on Unix an arping command is present for this.