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