Finding IP address and port number using socket api? - c

I am working on a code where I have need to find the sender's IP address,sender's port no and application layer packet sent by it.
I did it using Raw Sockets (SOCK_RAW), it runs fine and did the job for me but its too much clumsy.
Question: I can use SOCK_STREAM and get the application layer packet directly and that's really clean and simple method than using Raw socket but this way I won't be able to find the IP address and port number of the client. Is there any function to which I pass the socket descriptor and it tells me the IP address and port number of the other end. I read a few man pages but I could not find any.
I am using linux socket api in C language.
Thanks in advance. :)

When you call accept() to accept an incoming connection, *address is a structure that is filled in with the sender's IP address and port number.

the BSD socket implementation defines a function named getpeername() which allows to know the ip address and the port of the remote side of a tcp socket.
when you have any SOCK_STREAM connected socket, no matter which side first established the connection, you can call this function to get the informations you need. (this is far easier than a raw socket).

Related

UDP - Multi-server single client

I have a linux computer with a code in C that must communicate in UDP with 4 differents equipments. The computer sends differents commands to each equipment and receives responses, sometimes in parallel ...
I am a perfect beginner, and managed to communicate with one equipment using UDP socket. But now, i'm looking for a way to communicate with all these equipments, what i would like to call "multiple socket", but i don't know where to look/ what word to search to find a way ...
My linux computer is the client and all the equipment servers. I only have one eth port on the computer and will have to use a switch to have access to all the equipment. I would like to create functions like :
sendcmd(IPnumber, PORTnumber, cmd , ...)
readbuff(IPnumber, PORTnumber, buff, ...)
so i can choose which IP will received cmd ... i don't know if it's possible or if i need to open the socket, then close and redo the operation with another IP ...
So, if I ever managed to make myself understood, where should I look for a solution to my problem?
Thank you !
You can use a single UDP socket for your scenario. You can keep the socket open for the lifetime of your application.
UDP is not connection oriented. UDP sockets are also not classified into client sockets and server sockets. UDP sockets are always bound to a local port, either implicitly (typically for pure clients) or explicitly (which is usually the case for servers). In your case you do not care about the port for your UDP client.
To send to your four UDP server you can use sendto(). This lets you specify the destination IP address and port the UDP packet gets sent to.
To receive from your four UDP servers you can use recvfrom(). This will tell the IP address and port where the UDP packet came from.
You most likely want to have a receive loop of some kind. If you want to do anything else in your application you most likely want to either make recvfrom() non-blocking or you want to have the receive loop in its own thread. But this goes beyond your question.
The most important aspect of UDP is that it is not a protocol (despite its name which is misleading). It is one puzzle piece for a protocol. It is a tool to develop your own protocol. But I assume you already have a specific protocol at hand defined by your peripherals.

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

Configuring multiple UDP sockets on a single port

I'm trying to implement a peer-to-peer chat application using UDP and I was wondering about how to scale the program to multiple users.
As I understand it, UDP needs only one socket to send and receive data using the recvfrom and sendto functions. Using the data from the address fields passed to these functions, I can determine which user I'm communicating with.
I was wondering if I could create multiple UDP sockets on the same port for each peer that I'm talking to. That way, if data comes from a peer X, then the data goes to the UDP port and gets passed to the appropriate socket that is 'bound' to X's address.
Is there anyway I could do this while still using UDP?
Yes, you can specify SO_REUSEADDR (SO_REUSEPORT on Linux) before binding the UDP socket (all sockets including the first), and then connect each socket to the appropriate target, but it's really not necessary. Just dispatch each message arriving on a single socket according to its source-address.

Binding 40 Sockets to 40 different IP addresses

I am writing on UDP server/client application.
I want my single server to handle 40 clients at a time. For this, I want to create 40 dedicated threads, each dedicated for one single client. Since there are 40 threads one for each client, I want to create 40 dedicated sockets as well.
But the problem that:
I don't know what will be the 40 IP addresses to which I shall bind() my sockets. (since as far as I now, I have to bind() to my Server\s IP address.) Normally I bind() to "INADDR_ANY" when there is only single socket.
But what should be the IP addresses at which I should bind() each of my 40 sockets?
Please help me. Any comment/ help is appreciated.
One common way to do this with UDP is:
Server bind() to a well known port.
Client sends the initial packet to that well known port
Server receive the first packet from a client on the well known port.
Server creates a new socket with a random port
Server replies to the client from this new socket.
Client receives the reply, notices it comes from another port than the well known
server port, and uses that port as the destination for further communication.
You'll use the getpeername() call to learn the remote address.
Keep in mind that UDP is connection-less, you'll need some way to signal the end or time out you sockets.
bind only needs the local address, not the remote address.
If you want one socket for each client, then you'll need to use different ports for each (using bind). That way, each client can send its traffic to a dedicated port, and you can have a thread for each socket/port.
It's probably a better idea to only have one socket (and one port) though, and have logic in your code to assign traffic to a thread based on the remote address (retrieved using recvfrom eg.).
The usual way is to bind a single socket and accept incoming connections. Each connection will be assigned a unique socket by accept.
As you are using UDP, I would simply use TCP as described above to let the clients know of their respective server UDP addresses.
Create a single listening socket in a dedicated listening thread.
When it receives a new packet, use the packet's remote addr/port, or put a unique clientID in the packet payload, to uniquely identify the client.
Create a new thread for that client if one does not already exist, pass the packet to that thread for further processing, and go back to listening.
If a given client thread does not receive any packets for awhile, it can terminate itself.

How to broadcast a message in a network?

I'm working on a client-server application written in C. I want to broadcast a message to all the machines available on the local network.
How can I do that using the usual socket system calls in C?
Just send the message to the broadcast address of your subnet, which for 192.168.0.0/24 is 192.168.0.255, or just broadcast to 255.255.255.255.
you have to use UDP to send a broadcast message over a network. when creating your socket using the socket() function, specify AF_INET for the family parameter and SOCK_DGRAM for the type parameter. on some systems, you have to enable the sending of broadcast packet by setting the SO_BROADCAST socket option to 1, using setsockopt().
then use the sendto() function call to send a datagram, and use 255.255.255.255 as the destination address. (for datagram sockets, you don't need to call connect(), since there is no 'connection').
in standard implementations, this address broadcasts to all computer in the local network, this means that the packet will not cross gateway boundaries and will not be received by computers using a network mask diferent from the network mask of the sending computer.
Have a look at UDP sockets.
I recomend Beej's Guide to Network Programming. Have a look at 6.3 Datagram Sockets
You can use the special address of 255.255.255.255 to send a broadcast message to every computer on the local network.
For more info see section IP Network Broadcasting.

Resources