Back to index

nagios-plugins  1.4.16
Defines | Functions | Variables
check_tcp.c File Reference
#include "common.h"
#include "netutils.h"
#include "utils.h"
#include "utils_tcp.h"

Go to the source code of this file.

Defines

#define my_recv(buf, len)   read(sd, buf, len)
#define my_send(buf, len)   send(sd, buf, len, 0)
#define EXPECT   server_expect[0]
#define MAXBUF   1024
#define FLAG_SSL   0x01
#define FLAG_VERBOSE   0x02
#define FLAG_EXACT_MATCH   0x04
#define FLAG_TIME_WARN   0x08
#define FLAG_TIME_CRIT   0x10
#define FLAG_HIDE_OUTPUT   0x20
#define FLAG_MATCH_ALL   0x40

Functions

static int process_arguments (int, char **)
void print_help (void)
void print_usage (void)
int main (int argc, char **argv)

Variables

char * progname
const char * copyright = "1999-2008"
const char * email = "nagiosplug-devel@lists.sourceforge.net"
static char * SERVICE = "TCP"
static char * SEND = NULL
static char * QUIT = NULL
static int PROTOCOL = IPPROTO_TCP
static int PORT = 0
static int server_port = 0
static char * server_address = NULL
static char * server_send = NULL
static char * server_quit = NULL
static char ** server_expect
static size_t server_expect_count = 0
static size_t maxbytes = 0
static char ** warn_codes = NULL
static size_t warn_codes_count = 0
static char ** crit_codes = NULL
static size_t crit_codes_count = 0
static unsigned int delay = 0
static double warning_time = 0
static double critical_time = 0
static double elapsed_time = 0
static long microsec
static int sd = 0
static char buffer [MAXBUF]
static int expect_mismatch_state = STATE_WARNING
static size_t flags = FLAG_EXACT_MATCH

Define Documentation

#define EXPECT   server_expect[0]

Definition at line 55 of file check_tcp.c.

#define FLAG_EXACT_MATCH   0x04

Definition at line 85 of file check_tcp.c.

#define FLAG_HIDE_OUTPUT   0x20

Definition at line 88 of file check_tcp.c.

#define FLAG_MATCH_ALL   0x40

Definition at line 89 of file check_tcp.c.

#define FLAG_SSL   0x01

Definition at line 83 of file check_tcp.c.

#define FLAG_TIME_CRIT   0x10

Definition at line 87 of file check_tcp.c.

#define FLAG_TIME_WARN   0x08

Definition at line 86 of file check_tcp.c.

#define FLAG_VERBOSE   0x02

Definition at line 84 of file check_tcp.c.

#define MAXBUF   1024

Definition at line 79 of file check_tcp.c.

#define my_recv (   buf,
  len 
)    read(sd, buf, len)

Definition at line 46 of file check_tcp.c.

#define my_send (   buf,
  len 
)    send(sd, buf, len, 0)

Definition at line 47 of file check_tcp.c.


Function Documentation

int main ( int  argc,
char **  argv 
)

Definition at line 93 of file check_tcp.c.

{
       int result = STATE_UNKNOWN;
       int i;
       char *status = NULL;
       struct timeval tv;
       size_t len;
       int match = -1;

       setlocale (LC_ALL, "");
       bindtextdomain (PACKAGE, LOCALEDIR);
       textdomain (PACKAGE);

       /* determine program- and service-name quickly */
       progname = strrchr(argv[0], '/');
       if(progname != NULL) progname++;
       else progname = argv[0];

       len = strlen(progname);
       if(len > 6 && !memcmp(progname, "check_", 6)) {
              SERVICE = strdup(progname + 6);
              for(i = 0; i < len - 6; i++)
                     SERVICE[i] = toupper(SERVICE[i]);
       }

       /* set up a resonable buffer at first (will be realloc()'ed if
        * user specifies other options) */
       server_expect = calloc(sizeof(char *), 2);

       /* determine defaults for this service's protocol */
       if (!strncmp(SERVICE, "UDP", 3)) {
              PROTOCOL = IPPROTO_UDP;
       }
       else if (!strncmp(SERVICE, "FTP", 3)) {
              EXPECT = "220";
              QUIT = "QUIT\r\n";
              PORT = 21;
       }
       else if (!strncmp(SERVICE, "POP", 3) || !strncmp(SERVICE, "POP3", 4)) {
              EXPECT = "+OK";
              QUIT = "QUIT\r\n";
              PORT = 110;
       }
       else if (!strncmp(SERVICE, "SMTP", 4)) {
              EXPECT = "220";
              QUIT = "QUIT\r\n";
              PORT = 25;
       }
       else if (!strncmp(SERVICE, "IMAP", 4)) {
              EXPECT = "* OK";
              QUIT = "a1 LOGOUT\r\n";
              PORT = 143;
       }
#ifdef HAVE_SSL
       else if (!strncmp(SERVICE, "SIMAP", 5)) {
              EXPECT = "* OK";
              QUIT = "a1 LOGOUT\r\n";
              flags |= FLAG_SSL;
              PORT = 993;
       }
       else if (!strncmp(SERVICE, "SPOP", 4)) {
              EXPECT = "+OK";
              QUIT = "QUIT\r\n";
              flags |= FLAG_SSL;
              PORT = 995;
       }
       else if (!strncmp(SERVICE, "SSMTP", 5)) {
              EXPECT = "220";
              QUIT = "QUIT\r\n";
              flags |= FLAG_SSL;
              PORT = 465;
       }
       else if (!strncmp(SERVICE, "JABBER", 6)) {
              SEND = "<stream:stream to=\'host\' xmlns=\'jabber:client\' xmlns:stream=\'http://etherx.jabber.org/streams\'>\n";
              EXPECT = "<?xml version=\'1.0\'?><stream:stream xmlns=\'jabber:client\' xmlns:stream=\'http://etherx.jabber.org/streams\'";
              QUIT = "</stream:stream>\n";
              flags |= FLAG_HIDE_OUTPUT;
              PORT = 5222;
       }
       else if (!strncmp (SERVICE, "NNTPS", 5)) {
              server_expect_count = 2;
              server_expect[0] = "200";
              server_expect[1] = "201";
              QUIT = "QUIT\r\n";
              flags |= FLAG_SSL;
              PORT = 563;
       }
#endif
       else if (!strncmp (SERVICE, "NNTP", 4)) {
              server_expect_count = 2;
              server_expect = malloc(sizeof(char *) * server_expect_count);
              server_expect[0] = strdup("200");
              server_expect[1] = strdup("201");
              QUIT = "QUIT\r\n";
              PORT = 119;
       }
       else if (!strncmp(SERVICE, "CLAMD", 5)) {
              SEND = "PING";
              EXPECT = "PONG";
              QUIT = NULL;
              PORT = 3310;
       }
       /* fallthrough check, so it's supposed to use reverse matching */
       else if (strcmp (SERVICE, "TCP"))
              usage (_("CRITICAL - Generic check_tcp called with unknown service\n"));

       server_address = "127.0.0.1";
       server_port = PORT;
       server_send = SEND;
       server_quit = QUIT;
       status = NULL;

       /* Parse extra opts if any */
       argv=np_extra_opts (&argc, argv, progname);

       if (process_arguments (argc, argv) == ERROR)
              usage4 (_("Could not parse arguments"));

       if(flags & FLAG_VERBOSE) {
              printf("Using service %s\n", SERVICE);
              printf("Port: %d\n", server_port);
              printf("flags: 0x%x\n", (int)flags);
       }

       if(EXPECT && !server_expect_count)
              server_expect_count++;

       if(PROTOCOL==IPPROTO_UDP && !(server_expect_count && server_send)){
              usage(_("With UDP checks, a send/expect string must be specified."));
       }

       /* set up the timer */
       signal (SIGALRM, socket_timeout_alarm_handler);
       alarm (socket_timeout);

       /* try to connect to the host at the given port number */
       gettimeofday (&tv, NULL);

       result = np_net_connect (server_address, server_port, &sd, PROTOCOL);
       if (result == STATE_CRITICAL) return STATE_CRITICAL;

#ifdef HAVE_SSL
       if (flags & FLAG_SSL){
              result = np_net_ssl_init(sd);
              if (result == STATE_OK && check_cert == TRUE) {
                     result = np_net_ssl_check_cert(days_till_exp_warn, days_till_exp_crit);
              }
       }
       if(result != STATE_OK){
              np_net_ssl_cleanup();
              if(sd) close(sd);
              return result;
       }
#endif /* HAVE_SSL */

       if (server_send != NULL) {         /* Something to send? */
              my_send(server_send, strlen(server_send));
       }

       if (delay > 0) {
              tv.tv_sec += delay;
              sleep (delay);
       }

       if(flags & FLAG_VERBOSE) {
              if (server_send) {
                     printf("Send string: %s\n", server_send);
              }
              if (server_quit) {
                     printf("Quit string: %s\n", server_quit);
              }
              printf("server_expect_count: %d\n", (int)server_expect_count);
              for(i = 0; i < server_expect_count; i++)
                     printf("\t%d: %s\n", i, server_expect[i]);
       }

       /* if(len) later on, we know we have a non-NULL response */
       len = 0;
       if (server_expect_count) {

              /* watch for the expect string */
              while ((i = my_recv(buffer, sizeof(buffer))) > 0) {
                     status = realloc(status, len + i + 1);
                     memcpy(&status[len], buffer, i);
                     len += i;

                     /* stop reading if user-forced or data-starved */
                     if(i < sizeof(buffer) || (maxbytes && len >= maxbytes))
                            break;

                     if (maxbytes && len >= maxbytes)
                            break;
              }

              /* no data when expected, so return critical */
              if (len == 0)
                     die (STATE_CRITICAL, _("No data received from host\n"));

              /* force null-termination and strip whitespace from end of output */
              status[len--] = '\0';
              /* print raw output if we're debugging */
              if(flags & FLAG_VERBOSE)
                     printf("received %d bytes from host\n#-raw-recv-------#\n%s\n#-raw-recv-------#\n",
                            (int)len + 1, status);
              while(isspace(status[len])) status[len--] = '\0';

              match = np_expect_match(status,
                                server_expect,
                                server_expect_count,
                                (flags & FLAG_MATCH_ALL ? TRUE : FALSE),
                                (flags & FLAG_EXACT_MATCH ? TRUE : FALSE),
                                (flags & FLAG_VERBOSE ? TRUE : FALSE));
       }

       if (server_quit != NULL) {
              my_send(server_quit, strlen(server_quit));
       }
#ifdef HAVE_SSL
       np_net_ssl_cleanup();
#endif
       if (sd) close (sd);

       microsec = deltime (tv);
       elapsed_time = (double)microsec / 1.0e6;

       if (flags & FLAG_TIME_CRIT && elapsed_time > critical_time)
              result = STATE_CRITICAL;
       else if (flags & FLAG_TIME_WARN && elapsed_time > warning_time)
              result = STATE_WARNING;

       /* did we get the response we hoped? */
       if(match == FALSE && result != STATE_CRITICAL)
              result = expect_mismatch_state;

       /* reset the alarm */
       alarm (0);

       /* this is a bit stupid, because we don't want to print the
        * response time (which can look ok to the user) if we didn't get
        * the response we were looking for. if-else */
       printf("%s %s - ", SERVICE, state_text(result));

       if(match == FALSE && len && !(flags & FLAG_HIDE_OUTPUT))
              printf("Unexpected response from host/socket: %s", status);
       else {
              if(match == FALSE)
                     printf("Unexpected response from host/socket on ");
              else
                     printf("%.3f second response time on ", elapsed_time);
              if(server_address[0] != '/')
                     printf("port %d", server_port);
              else
                     printf("socket %s", server_address);
       }

       if (match != FALSE && !(flags & FLAG_HIDE_OUTPUT) && len)
              printf (" [%s]", status);

       /* perf-data doesn't apply when server doesn't talk properly,
        * so print all zeroes on warn and crit. Use fperfdata since
        * localisation settings can make different outputs */
       if(match == FALSE)
              printf ("|%s",
                            fperfdata ("time", elapsed_time, "s",
                            (flags & FLAG_TIME_WARN ? TRUE : FALSE), 0,
                            (flags & FLAG_TIME_CRIT ? TRUE : FALSE), 0,
                            TRUE, 0,
                            TRUE, socket_timeout)
                     );
       else
              printf("|%s",
                            fperfdata ("time", elapsed_time, "s",
                            (flags & FLAG_TIME_WARN ? TRUE : FALSE), warning_time,
                            (flags & FLAG_TIME_CRIT ? TRUE : FALSE), critical_time,
                            TRUE, 0,
                            TRUE, socket_timeout)
                     );

       putchar('\n');
       return result;
}

Here is the call graph for this function:

void print_help ( void  )
void print_usage ( void  )

Definition at line 389 of file check_cpqarray.c.

{
  printf("cpqarrayd [options]\n");
  printf("   -h         prints this text\n");
  printf("   -d         enables debugging\n");
}
static int process_arguments ( int  argc,
char **  argv 
) [static]

Variable Documentation

char buffer[MAXBUF] [static]

Definition at line 80 of file check_tcp.c.

const char* copyright = "1999-2008"

Definition at line 32 of file check_tcp.c.

char** crit_codes = NULL [static]

Definition at line 71 of file check_tcp.c.

size_t crit_codes_count = 0 [static]

Definition at line 72 of file check_tcp.c.

double critical_time = 0 [static]

Definition at line 75 of file check_tcp.c.

unsigned int delay = 0 [static]

Definition at line 73 of file check_tcp.c.

double elapsed_time = 0 [static]

Definition at line 76 of file check_tcp.c.

const char* email = "nagiosplug-devel@lists.sourceforge.net"

Definition at line 33 of file check_tcp.c.

Definition at line 81 of file check_tcp.c.

size_t flags = FLAG_EXACT_MATCH [static]

Definition at line 90 of file check_tcp.c.

size_t maxbytes = 0 [static]

Definition at line 68 of file check_tcp.c.

long microsec [static]

Definition at line 77 of file check_tcp.c.

int PORT = 0 [static]

Definition at line 60 of file check_tcp.c.

char* progname

Definition at line 31 of file check_tcp.c.

int PROTOCOL = IPPROTO_TCP [static]

Definition at line 59 of file check_tcp.c.

char* QUIT = NULL [static]

Definition at line 58 of file check_tcp.c.

int sd = 0 [static]

Definition at line 78 of file check_tcp.c.

char* SEND = NULL [static]

Definition at line 57 of file check_tcp.c.

char* server_address = NULL [static]

Definition at line 63 of file check_tcp.c.

char** server_expect [static]

Definition at line 66 of file check_tcp.c.

size_t server_expect_count = 0 [static]

Definition at line 67 of file check_tcp.c.

int server_port = 0 [static]

Definition at line 62 of file check_tcp.c.

char* server_quit = NULL [static]

Definition at line 65 of file check_tcp.c.

char* server_send = NULL [static]

Definition at line 64 of file check_tcp.c.

char* SERVICE = "TCP" [static]

Definition at line 56 of file check_tcp.c.

char** warn_codes = NULL [static]

Definition at line 69 of file check_tcp.c.

size_t warn_codes_count = 0 [static]

Definition at line 70 of file check_tcp.c.

double warning_time = 0 [static]

Definition at line 74 of file check_tcp.c.