xref: /linux-tools/misc/tcpportcheck.c (revision 8b1d656efaea4bf52ca12539e1b6e39d079e170b)
1 #define _GNU_SOURCE 1
2 
3 #include <stdio.h>
4 #include <stdlib.h>
5 #include <sys/types.h>
6 #include <sys/socket.h>
7 #include <unistd.h>
8 #include <fcntl.h>
9 #include <netinet/in.h>
10 #include <netinet/ip.h>
11 #include <netinet/tcp.h>
12 #include <arpa/inet.h>
13 #include <poll.h>
14 
15 
main(int argc,char * argv[])16 int main(int argc, char *argv[]) {
17     int sk, err, opt;
18     int port;
19     struct in_addr addr;
20     struct sockaddr_in saddr;
21     struct linger linger_opt;
22     struct pollfd polls[1];
23     if (argc!=3) {
24         printf("usage %s <ip> <port>\n", argv[0]);
25         return 1;
26     }
27     port = atoi(argv[2]); if (port<=0) {
28         printf("invalid port %s\n", argv[2]);
29         return 1;
30     }
31     if (inet_aton(argv[1], &addr) == 0) {
32         printf("invalie ip addr %s\n", argv[1]);
33         return 1;
34     }
35 
36     sk = socket(AF_INET, SOCK_STREAM, IPPROTO_IP);
37     err = fcntl(sk, F_SETFL, O_RDONLY|O_NONBLOCK);
38     if (err<0) { perror("fail to fcntl"); return 1; }
39     opt=1;
40     err = setsockopt(sk, SOL_TCP, TCP_NODELAY, &opt, sizeof(opt));
41     if (err<0) { perror("fail to set socke opt nodelay to 1"); return 1; }
42     opt=0;
43     err = setsockopt(sk, SOL_TCP, TCP_QUICKACK, &opt, sizeof(opt));
44     if (err<0) { perror("fail to set socke opt quickact to 0"); return 1; }
45     saddr.sin_family = AF_INET;
46     saddr.sin_port = htons(port);
47     saddr.sin_addr = addr;
48     connect(sk, &saddr, sizeof(saddr)); // non blocking, would reaturn -1
49     polls[0].fd=sk;
50     polls[0].events = POLLIN|POLLOUT|POLLRDHUP;
51     err = poll(polls, 1, 1000);
52     linger_opt.l_onoff=1;
53     linger_opt.l_linger=0;
54     setsockopt(sk, SOL_SOCKET, SO_LINGER, &linger_opt, sizeof(linger_opt));
55     close(sk);
56     if (err>0&&polls[0].revents==POLLOUT) printf("remote port active\n");
57     else { printf("remote port not active\n"); return 1; }
58     return 0;
59 }
60