We'll investigate both and select one or probably a mix.
Thanks again.
On 11. jan.. 2008, at 14.57, pierrick grasland wrote: Hello,
This is a small patch in order to support SIP protocol.
Based on http test, it send an OPTIONS to a sip component, and verify response status code.
Modified files :
monitor.h p.y l.l protocols/protocol.h protocols/protocol.c
New file :
sip.c
Utilization :
Like other protocol, with the following syntax :
CHECK host abc WITH address xyz IF FAILED PORT s [TYPE {tcp|udp|tcpssl}] PROTO(COL) sip [AND] [TARGET "sip:address@hidden"] [AND] [MAXFORWARD 6] THEN ALERT
A valid port number must be available, in order to contact SIP server.
Optional :
TARGET : you may specify an alternative recipient for the OPTIONS message, by adding a valid sip uri after this keyword, ie beginning by : sip:xxxx or sips:yyyy
MAXFORWARD : Limit the number of proxies or gateways that can forward the request to the next server. It's value is an integer in the range 0-255, set by default at 70. If max-forward = 0, the next server may respond 200 OK (test passed) or send a 483 Too Many Hops (test failed)
Examples :
monitrc :
check host openser_all with address 127.0.0.1 if failed port 5060 type udp protocol sip and target "sip:localhost:5060" and maxforward 6 then alert
with the following configuration for openser, it will respond a 200 OK (success)
openser configuration :
see openser.cfg (attach file)
Changes :
Index: monitor.h =================================================================== --- monitor.h (revision 1) +++ monitor.h (revision 2) @@ -454,6 +454,8 @@ Ssl_T SSL; /**< SSL definition */ Protocol_T protocol; /**< Protocol object for testing a port's service */ Request_T url_request; /**< Optional url client request object */ + char *target; /**< Optional target for testing a sip's service **/ + int maxforward; /**< Optional max forward parameter for testing a sip's service **/ /** For internal use */ struct myport *next; /**< next port in chain */
Index: l.l =================================================================== --- l.l (revision 1) +++ l.l (revision 2) @@ -205,6 +205,9 @@ rsync { return RSYNC; } tns { return TNS; } pgsql { return PGSQL; } +sip { return SIP; } +target { return TARGET; } +maxforward { return MAXFORWARD; } mode { return MODE; } active { return ACTIVE; } passive { return PASSIVE; }
Index: p.y =================================================================== Index: p.y =================================================================== --- p.y (revision 1) +++ p.y (revision 5) @@ -235,6 +235,8 @@ static void setsyslog(char *); static void describeAction(Action_T); static Command_T copycommand(Command_T); + static int verifyMaxForward(int); /** Verify Max Forward validity **/ + static char * verifyTarget(char *); /** Verify To Uri validity **/ %} @@ -255,7 +257,7 @@ %token ALERT NOALERT MAILFORMAT UNIXSOCKET SIGNATURE %token TIMEOUT RESTART CHECKSUM EVERY %token DEFAULT HTTP APACHESTATUS FTP SMTP POP IMAP CLAMAV NNTP NTP3 MYSQL DNS -%token SSH DWP LDAP2 LDAP3 RDATE RSYNC TNS PGSQL POSTFIXPOLICY +%token SSH DWP LDAP2 LDAP3 RDATE RSYNC TNS PGSQL POSTFIXPOLICY SIP %token <string> STRING PATH MAILADDR MAILFROM MAILSUBJECT %token <string> MAILBODY SERVICENAME STRINGNAME %token <number> NUMBER PERCENT LOGLIMIT CLOSELIMIT DNSLIMIT KEEPALIVELIMIT @@ -275,6 +277,8 @@ %token EXEC UNMONITOR ICMP ICMPECHO NONEXIST INVALID DATA RECOVERED PASSED %token URL CONTENT PID PPID FSFLAG %token <url> URLOBJECT +%token <string> TARGET +%token <number> MAXFORWARD %left GREATER LESS EQUAL NOTEQUAL @@ -925,6 +929,9 @@ | PROTOCOL MYSQL { portset.protocol= addprotocol(P_MYSQL); } + | PROTOCOL SIP target maxforward { + portset.protocol= addprotocol(P_SIP); + } | PROTOCOL NNTP { portset.protocol= addprotocol(P_NNTP); } @@ -969,6 +976,17 @@ | EXPECT STRING { addgeneric(&portset, NULL, $2); FREE($2);} ; +target : /* EMPTY */ + | TARGET STRING { + portset.target = verifyTarget($2); + FREE($2); + } + +maxforward : /* EMPTY */ + | MAXFORWARD NUMBER { + portset.maxforward = verifyMaxForward($2); + } + request : /* EMPTY */ | REQUEST PATH { portset.request= Util_urlEncode($2); @@ -2006,7 +2024,8 @@ p->SSL.version= port->SSL.version; } } - + p->target= port->target; + p->maxforward= port->maxforward; p->next= current->portlist; current->portlist= p; @@ -2474,6 +2493,7 @@ case P_RSYNC: return create_rsync(); case P_TNS: return create_tns(); case P_PGSQL: return create_pgsql(); + case P_SIP: return create_sip(); } return create_default(); @@ -3439,3 +3459,30 @@ return copy; } +/* Return a valid max forward value for SIP header */ + +static int verifyMaxForward(int mf) { + + ASSERT(mf); + int max = 70; + + if (mf >= 0 && mf <= 255) { + max = mf; + } + return max; +} + + +/* Verify to URI, in order to allow user to modify it */ + +static char * verifyTarget(char * target) { + + ASSERT(target); + + if (target != NULL) { + return xstrdup(target); + } + + return NULL; +} +
Index: protocol.c =================================================================== --- protocol.c (revision 1) +++ protocol.c (revision 2) @@ -55,6 +56,7 @@ static Protocol_T myrsync= NULL; static Protocol_T mytns= NULL; static Protocol_T mypgsql= NULL; +static Protocol_T mysip= NULL; /** @@ -63,7 +65,7 @@ * * @author Jan-Henrik Haukeland, <address@hidden> * - * @version \$Id: protocol.c,v 1.30 2007/07/25 12:54:33 hauk Exp $ + * @version \$Id: protocol.c ,v 1.29 2007/01/03 09:31:02 martinp Exp $ * * @file */ @@ -96,6 +98,7 @@ FREE(myrsync); FREE(mytns); FREE(mypgsql); + FREE(mysip); } @@ -317,3 +320,11 @@ return mypgsql; } +void *create_sip() { + if(mysip == NULL) { + NEW(mysip); + mysip->name= "SIP"; + mysip->check= check_sip; + } + return mysip; +}
Index: protocol.h =================================================================== --- protocol.h (revision 1) +++ protocol.h (revision 2) @@ -48,7 +49,9 @@ #define P_TNS 20 #define P_PGSQL 21 #define P_CLAMAV 22 +#define P_SIP 23 + void gc_protocols(); /* Protocol Factory routines */ @@ -74,6 +77,7 @@ void* create_rsync(); void* create_tns(); void* create_pgsql(); +void* create_sip(); /* "Package" locale Protocol routines */ int check_apache_status(Socket_T); @@ -98,6 +102,7 @@ int check_rsync(Socket_T); int check_tns(Socket_T); int check_pgsql(Socket_T); +int check_sip(Socket_T); #endif
Index: sip.c =================================================================== /* * Copyright (C), 2000-2007 by the monit project group. * All Rights Reserved. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/ >. */
#include <config.h>
#ifdef HAVE_STDIO_H #include <stdio.h> #endif
#ifdef HAVE_ERRNO_H #include <errno.h> #endif
#ifdef HAVE_STRING_H #include < string.h> #endif
#ifdef HAVE_TIME_H #include <time.h> #endif
#ifdef HAVE_STDLIB_H #include <stdlib.h> #endif
#include "protocol.h"
/** * * A SIP test. * * This test has been created in order to construct valid SIP message, even with a low poll cycle. * (In case of low poll cycle, chance are high for a misinterpretation of the generic test by the SIP AS. It will considered it for a retransmission, not for a new message) * * Send an OPTIONS request * and check the server's status code. * * The status code must be between 200 and 300 * Return TRUE if the status code is OK, otherwise FALSE * * In this current version, redirection are not supported. * * @author Grasland pierrick <address@hidden> * @version \$Id: sip.c,v 1.2 2007/01/03 09:31:02 martinp Exp $ * * @file */ /* -------------------------------------------------------------- Prototypes */ void generate_message(int type, int port, char * sent_message, const char * target, int maxforward); /* -------------------------------------------------------------- Public*/ int check_sip(Socket_T s) {
Port_T P; char buf[STRLEN+1]; char sent_message[STRLEN+1]; int status = 0; char *target = NULL; int maxforward = 0; ASSERT(s);
P= socket_get_Port(s);
ASSERT(P); target = P->target?P->target:"sip:address@hidden"; maxforward = P->maxforward; DEBUG("SIP: Beginning test\n"); generate_message(P->type, P->port, sent_message, target, maxforward); DEBUG(sent_message); if(socket_print(s, sent_message) < 0) { LogError("SIP: error sending data -- %s\n", STRERROR); return FALSE; }
if(!socket_readln(s, buf, sizeof(buf))) { LogError("SIP: error receiving data -- %s\n", STRERROR); return FALSE; }
Util_chomp(buf); if(! sscanf(buf, "%*s %d", &status)) { LogError("SIP error: cannot parse SIP status in response: %s\n", buf); return FALSE; } DEBUG("Response status: %d\n", status); if(status >= 400) { LogError("SIP error: Server returned status %d\n", status); return FALSE; } if(status >= 300 && status < 400) { LogError("SIP info: Server redirection. Returned status %d\n", status); return FALSE; } if(status >= 101 && status < 200) { LogError("SIP error: Provisionnal response . Returned status %d\n", status); return FALSE; } DEBUG("SIP: Ending test\n"); return TRUE; }
/*----------------------------------------------------------------------------------------- Private*/
void generate_message(int socket_type, int port, char * sent_message, const char * target, int maxforward) { int i; /* some change are needed if socket use TCP or UDP */ char * type = "TCP"; char * rport = ""; if (socket_type == 1) { type="TCP"; rport=""; } else if (socket_type == 2) { type="UDP"; rport="rport"; } /* initialization of random param */ srand(time(NULL)+socket_type); for (i=0; i <port%100; i++) { rand(); srand(rand()); } /* OPTIONS message generation */ sprintf(sent_message, "OPTIONS %s SIP/2.0\r\n" "Via: SIP/2.0/%s pcmonit;branch=z9hG4bK%i;%s\r\n" "To: <%s>\r\n" "From: <sip:address@hidden>;tag=%i\r\n" "Max-Forwards:%d\r\n" "Call-Id: %i\r\n" "CSeq: 1 OPTIONS\r\n" "Content-Length: 0\r\n\r\n", target, type, rand(), rport, target, rand(), maxforward, rand()); }
-- Grasland Pierrick ENSSAT - LSI 3 <l.l><monitor.h><protocol.c><protocol.h><sip.c><p.y><openser.cfg>_______________________________________________ monit-dev mailing list address@hidden http://lists.nongnu.org/mailman/listinfo/monit-dev
|