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
Related
I'm attempting to have two daemons running on the same port and IP but one is a server and the other is a client. Is there a method using socket options that would allow each socket to have a copy of the packet and let the daemons filter out the messages based on the protocol? It looks like reuse address blocks the first configured port and reuse port might just balance the packet between the two daemons.
Otherwise, I guess create another daemons to read the socket and send the packets to the correct daemon.
Thanks
You are correct at the end, you will need to have a third part that binds to the port and forwards the packets to the correct daemon.
The other way to do it would be to use three ports and use a firewall to redirect from the front end port to the backend ports; but that is a lot more complicated and not portable. But in the end you could use QOS or something. There is a wide range of possible types of use case behind the word protocol.
If the UDP packets you are receiving are multicast or broadcast packets, then you can set SO_REUSEADDR (and, for BSD-based OS's, SO_REUSEPORT) on the socket (using setsockopt()) before bind()-ing the socket, and then both sockets will receive a copy of each incoming UDP packet. (If the UDP packets are regular old unicast packets, OTOH, then doing the above will result in each received packet being received by only one of the two UDP sockets, which isn't what you want).
Note, however: You refer to the two daemons as being a "client" and a "server" -- the implication of those terms is that the two daemons are going to communicate with each other. If that is the case, then the typical approach would be to have the server-daemon bind to a well-known port number, and the client-daemon could bind to any port number (e.g. it could pass 0 as the port-number to bind(), and let the OS choose an available port-number for it). Then the client-daemon could start the conversation by sending one or more UDP packets to the server's well-known port number, and the server can find out which port the client is sending from (and therefore what port to send reply packets to) by examining the fifth argument of its recvfrom() call. In this case there is no need for the two programs to bind to the same port, and therefore no need for packet-forwarding.
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.
Currently, I have working, functioning code to pass messages between two programs I have written. Here's the scheme I'm using:
Program A
a_tx_socket -> Send Data on 127.0.0.1, Port A
a_rx_socket -> Receive Data on 127.0.0.1, Port B
Program B
b_tx_socket -> Send Data on 127.0.0.1, Port B
b_rx_socket -> Receive Data on 127.0.0.1, Port A
Note that I call bind() on the sockets that receive data (a_rx_socket and b_rx_socket). Each socket is created with a call to the socket() system call.
Now, for my question... is there a way to get rid of one port? Namely can I send/receive on the loopback address using only one port? How would I make sure that Program A/B does not receive data that it sent? Is this worth exploring for any reason (performance/maintainability/fun/etc)?
Only one process at a time can bind to a given socket address. Subsequent attempts to bind will get EADDRINUSE, meaning that the address is already in use.
For ip addresses, the socket address is made up of the port and the IP address. See 'man 7 ip' for details.
Therefore, you need two ports, because otherwise only one of your two programs would be able to bind (and therefore receive packets).
If your pair of programs is always going to be on the same machine, you might want to use unix domain sockets instead, as they would be more efficient for that use case.
I am writing a client/server program using C sockets. I am specifying that the server can listen on any network interface by using INADDR_ANY in sockaddr_in.sin_addr.s_addr. This is equivalent to an IP of 0.0.0.0. Is it possible for me to get the actual IP that the server is listening on? (e.g. 192.168.1.100)
When you bind a listening socket to INADDR_ANY, the socket listens on all available local IPs. There is no way to determine from the socket which IP(s) it is listening on. If you need that information, then you have to enumerate the local IPs separately (in which case you could just bind() each IP to its own socket individually if you need to retreive pre-accept binding details). However, once accept() has returned an established client connection, you can use getsockname() on the accepted socket to know which specific IP accepted the connection.
I have finally been able to find a solution that works.
Edit: link is dead so see: Internet Archive link.
Hopefully it can be helpful to others as it has been to me.
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).