Get all hosts on LAN network in C? - c

Is it possible to get all the hosts on a LAN network(using C). I need to get the IP addresses and host names.

As explained in this answer, the to ping all hosts in your subnet and see which respond or access the ARP cache. The first approach is accomplished by creating a raw socket using
int sock = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP));
However, raw sockets basically give you only the IP header so you need to construct the ICMP echo packet yourself. After you constructed it, then you just send them to every IP in the subnet using sendto() and wait for response. For the second approach I suggest reading something like this.
As for determining the host names, it depends on whether the hosts have DNS or NETBIOS names. If you have a DNS configured on your LAN, you may get away with calling getaddrinfo() on the the addresses that respond. Unfortunately, I do not have any idea how to find out the NETBIOS name of any given IP.

Related

Check incoming interface on TCP socket

In network programming (C & Linux) with a TCP socket, how can I check the interface that received the packet. I know this can be done very easily with a SOCK_DGRAM and the IP option IP_PKTINFO, but this option does not work on SOCK_STREAM. In this case (for what im programming) I must know the interface that received the packet (the respond that gives back the server depends on that).
One possible solution that I found is to use SOCK_RAW and IPPROTO_TCP (with SOCK_RAW I can set the IP_PKTINFO option) but that implies that i'll be receiving all the TCP traffic that arrives to the machine and i don't want that. Another possible solution that I'm thinking is to check the destination IP against the routing table and get the exit interface from there but what about IPv6? What if the destiny IP its IPv6 link-local?
If anyone has another solution or idea I'll be glad to read it. Thanks in advance
When your TCP server accepted a client connection, you will have a socket to represent the connection, you could call getsockname on the socket, it will give you the address associated on the socket, namely the ip addresses on your side.
Next step, you can call getifaddrs to get all the interfaces and their information on your system, including name(like eth0) and ip address. At this point, you can search this list with the ip obtained previously via getsockname, you can get the interface you want as a result.
reference:
http://linux.die.net/man/2/getsockname
http://linux.die.net/man/3/getifaddrs

How to know the various IP addresses of the server using C, Linux, Socket?

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.

How to multicast to specific IP addresses?

I found a multicasting example at http://ntrg.cs.tcd.ie/undergrad/4ba2/multicast/antony/example.html that is simple enough. In our network, we intend to run the client app as a daemon on each of the machines. However, the server needs to multicast files only to specific clients at a time.
Is there a way to extend multicasting to specific IP addresses? If so, how do I extend the server code to do so?
Otherwise, I am thinking I will initially send a packet that contains the list of acceptable IPs. If the client sees that its IP is not on the list, it will simply ignore the packets that follow. This might work as I have complete control over the server and the client code. Is this a reasonable strategy?
If you know you're only sending to a single IP, it's just as easy for the server to send to an unicast IP address as it is to send to a multicast IP address. The socket on the client side that is set up to read multicast packets can also receive unicast packets sent to it directly.
It's a matter of setting the sin_addr field in the struct sockaddr_in you're using to pass to sendto(). So if 230.1.2.3 is your multicast address and 192.168.1.2 is the specific client you want to send to, instead of this:
addr.sin_addr.s_addr=inet_addr("230.1.2.3");
You do this:
addr.sin_addr.s_addr=inet_addr("192.168.1.2");
The method of having the payload of the multicast packet containing the list of acceptable IPs is also a good solution. This will allow you the flexibility to send to a subset of clients that are listening. Just make sure the packet has a well defined format. Having an application header that contains the number of IPs listed and/or the offset of the main payload is a good way to handle this.
EDIT:
If you want something off the shelf that can multicast files reliably, you can use an application I created called UFTP. It also has a unicast mode if you need that.

Network Discovery of Servers

Ok, so I understand that communication between a client computer and a server computer can be initiated in windows with the creation of a socket between the two computers, but every tutorial that I have seen depends on the End User knowing the IP address of the computer that they wish to connect to.
In local network LAN games, however, the clients somehow autodetect the server. How is this done? Does the client autocheck every possible IP, is there some sort of "GetDetectedIPs" api, etc?
Im looking for answers that can be implemented in standard WIN32 API in straight C. No MFC, .NET, or C++ please. Thank you.
The technique you need is called broadcasting. It's used, for example, in BOOTP and DHCP protocols.
Sending a packet with broadcast destination address results in it being received by all devices in LAN. Broadcast address is an IP address in which the host identification field is filled with ones:
bcast_addr = ~netmask | my_addr;
The discovery process is usually like follows:
The client sends a UDP datagram with broadcast destination address at specific port.
The server listens on this port and receives the datagram. Other computers discard it.
Server sends all the necessary info about itself to the client by a usual UDP datagram.
This is usually done with zero-conf. Microsoft version of it is Simple Service Discovery Protocol.
You could just let the client send an UDP packet to every IP in a specified range and let the server answer with another UDP packet.

Discovering DHCP servers using multicast (224.0.0.12) in GNU/Linux/C

This question might stem from a fundamental misunderstanding of IP multicast, so please correct me if I'm off base.
I'm trying to write C code to find the IP address of all the DHCP servers on the network. The use case is this:
Client broadcasts DHCP discover.
My proprietary relay agent picks up the packet, adds some essential information, and forwards it UNICAST to the DHCP server at a known IP address.
The problem I'm having is telling the relay agent where the DHCP server(s) is(are). I found that multicast address 224.0.0.12 is reserved by IANA for DHCP servers, so I figured I'd just configure the servers to listen for that multicast traffic. But whenever I configure a linux socket option to IP_ADD_MEMBERSHIP to 224.0.0.12, it uses IGMP, which is an entirely separate protocol which I don't want to have to implement.
Am I just misunderstanding how multicast works? Shouldn't I be able to send a ping from the relay agent to 224.0.0.12 and have it return a ping response from all DHCP servers?
Additional Info:
the interfaces on all the boxes do have MULTICAST listed when I do an ifconfig
I have added the multicast route using ip route add 224.0.0.0/4 dev eth0 on all boxes
Perhaps you should do what clients do - broadcast (not multicast!) on the target network with a DHCPDISCOVER packet? I have a couple of running, working DHCP servers and none of them are listening on the 224 network.
You'll probably also want to either request your existing address, or send along a DHCPRELEASE for any offers you get back, so as not to tie up addresses in fake reservations on the servers.
In a general IPv4 setting use broadcast to UDP port 67, not multicast. The broadcast request should be answered by all DHCP servers on your network. Take a look at the details explained on the Wikipedia page or read the broadcast explanation in RFC 2131, Section 3. Also see this thread.

Resources