Given a local IP and port for an established TCP session, can I find out which side sent the initial SYN? That is, was this connection actively or passively opened? I need something that works in C/C++ on Linux. A hacky way might be to socket()/listen() and catch EADDRINUSE but I was hoping for something cleaner. I'm not even sure if the kernel tracks this once the session is established.
EDIT: I'd also prefer not to call out to netstat (or even ss) as both are too slow with many sockets open. This code will be called often.
Always the client makes an active connection, by sending a SYN(to the server). So, given a local IP and port number, check if its a listening socket using the following command:
netstat --listening | grep given_ip:given_port
If it is not listed here, then it is a client-side socket, thus initiates a SYN. If its there, then its a listening socket and hence it has received a SYN.
The corresponding code looks as follows:
system("netstat --listening | grep given_ip:given_port > tmp.txt");
int fd = open("tmp.txt", O_RDONLY);
char buf[100] ;
if(read(fd,buf,100)>0)
printf("The socket has received a SYN!");
else
printf("The socket has sent a SYN!");
EDIT:
If you feel netstat has poor speed to scan the entire ports, then the only way to achieve the fastness is to open a raw socket and set it to receive all the TCP packets.
Process only those packets which contain a SYN in them. Now, store both source address:port and destination address:port into two tables. One that is a sender of SYN and one that is a receiver.
Now, when you are given a port and ip-address, make a scan over the data stored so far. You can also use STL map of C++ to achieve faster results.
Since there can be many requests, the map may get filled up swiftly, making the look-ups slow. I advice you to process the FIN packets also and based on that remove the corresponding entries from the table.