Friday, November 24, 2017

Adding TCP service checking to Node-Red

The following C program can be used with Node-Red to provide service indicators in a dashboard. Basically, it accepts two arguments: the IP address and the port number of the target system/service. It then attempts to connect to that IP and port and returns either the word "on" or the word "off". When run with Node-Reds timer and exec modules, it provides a dashboard status for each of the targeted services.

Save the following to "portcheck.c" and compile it by running "gcc -o portcheck portcheck.c"

  // Tim Kramer - 18 Nov 2017

  // adapted from Silver Moon's code at:
  // www.binarytides.com/tcp-connect-port-scanner-c-code-linux-sockets/

  // Purpose of this is to work with Node-Red in checking on services.
  // This determines if a specific port on a specific machine is open
  // and returns "on" if a port is open, or "off" if port is closed.

  // This will exit without two arguments
  // Syntax:  portcheck IP_ADDR PORT

  // Possible issue: takes a few seconds to timeout if target machine 
  // is offline

  #include <stdio.h>
  #include <sys/socket.h>
  #include <errno.h>
  #include <netdb.h>
  #include <string.h>
  #include <stdlib.h>

  int main(int argc, char **argv){

     //###############################################//
     // check if there are two arguments, exit if not //
     //###############################################//

     if(argc!=3) {
        printf("usage: portcheck IP PORT\n");
        exit(1);
     }

     //##################################//
     // declare variables and structures //
     //##################################//

     struct hostent *host;
     int err, i, sock;
     struct sockaddr_in sa;

     //######################//
     // set up the sa struct //
     //######################//

     strncpy((char*)&sa, "", sizeof sa);
     sa.sin_family = AF_INET;

     //######################################//
     // add the IP and port to the sa struct //
     //######################################//

     sa.sin_addr.s_addr = inet_addr(argv[1]);  
     sa.sin_port=htons(atoi(argv[2]));

     //#######################//
     // check the IP and port //
     //#######################//

     sock = socket(AF_INET, SOCK_STREAM, 0);
     if(socket < 0){
        exit(1);    
     }
     err = connect(sock, (struct sockaddr*)&sa, sizeof sa);

     //######################################################//
     // return "on" if port is open, "off" if port is closed //
     //######################################################//

     if (err < 0){
        printf("off");
     } else {
        printf("on");
     }

     close(sock);
     fflush(stdout);
     return 0;
  }