summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--usr.sbin/hostated/Makefile7
-rw-r--r--usr.sbin/hostated/buffer.c3
-rw-r--r--usr.sbin/hostated/check_http.c3
-rw-r--r--usr.sbin/hostated/check_icmp.c3
-rw-r--r--usr.sbin/hostated/check_send_expect.c141
-rw-r--r--usr.sbin/hostated/check_tcp.c8
-rw-r--r--usr.sbin/hostated/control.c3
-rw-r--r--usr.sbin/hostated/hce.c3
-rw-r--r--usr.sbin/hostated/hostated.c3
-rw-r--r--usr.sbin/hostated/hostated.conf.517
-rw-r--r--usr.sbin/hostated/hostated.h9
-rw-r--r--usr.sbin/hostated/imsg.c3
-rw-r--r--usr.sbin/hostated/parse.y46
-rw-r--r--usr.sbin/hostated/pfe.c3
-rw-r--r--usr.sbin/hostated/pfe_filter.c3
-rw-r--r--usr.sbin/hoststated/Makefile7
-rw-r--r--usr.sbin/hoststated/buffer.c3
-rw-r--r--usr.sbin/hoststated/check_http.c3
-rw-r--r--usr.sbin/hoststated/check_icmp.c3
-rw-r--r--usr.sbin/hoststated/check_send_expect.c141
-rw-r--r--usr.sbin/hoststated/check_tcp.c8
-rw-r--r--usr.sbin/hoststated/control.c3
-rw-r--r--usr.sbin/hoststated/hce.c3
-rw-r--r--usr.sbin/hoststated/hoststated.c3
-rw-r--r--usr.sbin/hoststated/hoststated.conf.517
-rw-r--r--usr.sbin/hoststated/hoststated.h9
-rw-r--r--usr.sbin/hoststated/imsg.c3
-rw-r--r--usr.sbin/hoststated/parse.y46
-rw-r--r--usr.sbin/hoststated/pfe.c3
-rw-r--r--usr.sbin/hoststated/pfe_filter.c3
-rw-r--r--usr.sbin/relayd/Makefile7
-rw-r--r--usr.sbin/relayd/buffer.c3
-rw-r--r--usr.sbin/relayd/check_icmp.c3
-rw-r--r--usr.sbin/relayd/check_tcp.c8
-rw-r--r--usr.sbin/relayd/control.c3
-rw-r--r--usr.sbin/relayd/hce.c3
-rw-r--r--usr.sbin/relayd/imsg.c3
-rw-r--r--usr.sbin/relayd/parse.y46
-rw-r--r--usr.sbin/relayd/pfe.c3
-rw-r--r--usr.sbin/relayd/pfe_filter.c3
-rw-r--r--usr.sbin/relayd/relayd.c3
-rw-r--r--usr.sbin/relayd/relayd.conf.517
-rw-r--r--usr.sbin/relayd/relayd.h9
43 files changed, 568 insertions, 53 deletions
diff --git a/usr.sbin/hostated/Makefile b/usr.sbin/hostated/Makefile
index c04e70f3036..16a06450a62 100644
--- a/usr.sbin/hostated/Makefile
+++ b/usr.sbin/hostated/Makefile
@@ -1,8 +1,9 @@
-# $OpenBSD: Makefile,v 1.1 2006/12/16 11:45:07 reyk Exp $
+# $OpenBSD: Makefile,v 1.2 2007/01/08 13:37:26 reyk Exp $
PROG= hostated
-SRCS= parse.y log.c control.c buffer.c imsg.c hostated.c \
- pfe.c pfe_filter.c hce.c check_icmp.c check_tcp.c check_http.c
+SRCS= parse.y log.c control.c buffer.c imsg.c hostated.c \
+ pfe.c pfe_filter.c hce.c \
+ check_icmp.c check_tcp.c check_http.c check_send_expect.c
MAN= hostated.8 hostated.conf.5
LDADD= -levent
diff --git a/usr.sbin/hostated/buffer.c b/usr.sbin/hostated/buffer.c
index 3abe27b1e62..547d65ed859 100644
--- a/usr.sbin/hostated/buffer.c
+++ b/usr.sbin/hostated/buffer.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: buffer.c,v 1.1 2006/12/16 11:45:07 reyk Exp $ */
+/* $OpenBSD: buffer.c,v 1.2 2007/01/08 13:37:26 reyk Exp $ */
/*
* Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
@@ -29,6 +29,7 @@
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
+#include <regex.h>
#include "hostated.h"
diff --git a/usr.sbin/hostated/check_http.c b/usr.sbin/hostated/check_http.c
index b081c1ce2fa..899a240f7dc 100644
--- a/usr.sbin/hostated/check_http.c
+++ b/usr.sbin/hostated/check_http.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: check_http.c,v 1.4 2006/12/25 19:05:41 reyk Exp $ */
+/* $OpenBSD: check_http.c,v 1.5 2007/01/08 13:37:26 reyk Exp $ */
/*
* Copyright (c) 2006 Pierre-Yves Ritschard <pyr@spootnik.org>
*
@@ -28,6 +28,7 @@
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
+#include <regex.h>
#include "hostated.h"
diff --git a/usr.sbin/hostated/check_icmp.c b/usr.sbin/hostated/check_icmp.c
index 2880d4f5e84..ae18a97cc88 100644
--- a/usr.sbin/hostated/check_icmp.c
+++ b/usr.sbin/hostated/check_icmp.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: check_icmp.c,v 1.5 2007/01/03 09:45:29 reyk Exp $ */
+/* $OpenBSD: check_icmp.c,v 1.6 2007/01/08 13:37:26 reyk Exp $ */
/*
* Copyright (c) 2006 Pierre-Yves Ritschard <pyr@spootnik.org>
@@ -33,6 +33,7 @@
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
+#include <regex.h>
#include "hostated.h"
diff --git a/usr.sbin/hostated/check_send_expect.c b/usr.sbin/hostated/check_send_expect.c
new file mode 100644
index 00000000000..0a1aa4c7db7
--- /dev/null
+++ b/usr.sbin/hostated/check_send_expect.c
@@ -0,0 +1,141 @@
+/* $OpenBSD: check_send_expect.c,v 1.1 2007/01/08 13:37:26 reyk Exp $ */
+/*
+ * Copyright (c) 2006 Pierre-Yves Ritschard <pyr@spootnik.org>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <sys/types.h>
+#include <sys/queue.h>
+#include <sys/socket.h>
+#include <sys/param.h>
+#include <net/if.h>
+#include <limits.h>
+#include <event.h>
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <regex.h>
+
+#include "hostated.h"
+
+void se_validate(struct ctl_tcp_event *);
+void se_read(int, short, void *);
+
+void
+se_validate(struct ctl_tcp_event *cte)
+{
+ u_char *b;
+
+ /*
+ * ensure string is nul-terminated.
+ */
+ b = buf_reserve(cte->buf, 1);
+ if (b == NULL)
+ fatal("out of memory");
+ *b = '\0';
+ if (regexec(&cte->table->regx, cte->buf->buf, 0, NULL, 0) == 0)
+ cte->host->up = HOST_UP;
+ else
+ cte->host->up = HOST_DOWN;
+
+ /*
+ * go back to original position.
+ */
+ cte->buf->wpos--;
+}
+
+void
+se_read(int s, short event, void *arg)
+{
+ ssize_t br;
+ char rbuf[SMALL_READ_BUF_SIZE];
+ struct timeval tv;
+ struct timeval tv_now;
+ struct ctl_tcp_event *cte = arg;
+
+ if (event == EV_TIMEOUT) {
+ cte->host->up = HOST_DOWN;
+ buf_free(cte->buf);
+ hce_notify_done(cte->host, "se_read: timeout");
+ return;
+ }
+ br = read(s, rbuf, sizeof(rbuf));
+ log_debug("se_read: %d bytes read", br);
+ if (br == 0) {
+ cte->host->up = HOST_DOWN;
+ se_validate(cte);
+ buf_free(cte->buf);
+ hce_notify_done(cte->host, "se_read: connection closed");
+ } else if (br == -1) {
+ cte->host->up = HOST_DOWN;
+ buf_free(cte->buf);
+ hce_notify_done(cte->host, "se_read: read failed");
+ } else {
+ buf_add(cte->buf, rbuf, br);
+ bcopy(&cte->table->timeout, &tv, sizeof(tv));
+ if (gettimeofday(&tv_now, NULL))
+ fatal("se_read: gettimeofday");
+ timersub(&tv_now, &cte->tv_start, &tv_now);
+ timersub(&tv, &tv_now, &tv);
+ se_validate(cte);
+ if (cte->host->up == HOST_UP) {
+ buf_free(cte->buf);
+ hce_notify_done(cte->host, NULL);
+ } else
+ event_once(s, EV_READ|EV_TIMEOUT, se_read, cte, &tv);
+ }
+}
+
+void
+start_send_expect(struct ctl_tcp_event *cte)
+{
+ int bs;
+ int pos;
+ int len;
+ char *req;
+ struct timeval tv;
+ struct timeval tv_now;
+
+ req = cte->table->sendbuf;
+ pos = 0;
+ len = strlen(req);
+ if (len) {
+ do {
+ bs = write(cte->s, req + pos, len);
+ if (bs <= 0) {
+ log_warnx("send_se_data: cannot send");
+ cte->host->up = HOST_DOWN;
+ hce_notify_done(cte->host,
+ "start_send_expect: write");
+ return;
+ }
+ pos += bs;
+ len -= bs;
+ } while (len > 0);
+ }
+
+ if ((cte->buf = buf_dynamic(SMALL_READ_BUF_SIZE, UINT_MAX)) == NULL)
+ fatalx("send_se_data: cannot create dynamic buffer");
+
+ log_debug("start_send_expect: reading");
+
+ bcopy(&cte->table->timeout, &tv, sizeof(tv));
+ if (gettimeofday(&tv_now, NULL))
+ fatal("start_send_expect: gettimeofday");
+ timersub(&tv_now, &cte->tv_start, &tv_now);
+ timersub(&tv, &tv_now, &tv);
+ event_once(cte->s, EV_READ|EV_TIMEOUT, se_read, cte, &tv);
+}
diff --git a/usr.sbin/hostated/check_tcp.c b/usr.sbin/hostated/check_tcp.c
index 93cf8dd7041..888edb8da31 100644
--- a/usr.sbin/hostated/check_tcp.c
+++ b/usr.sbin/hostated/check_tcp.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: check_tcp.c,v 1.4 2006/12/25 19:05:41 reyk Exp $ */
+/* $OpenBSD: check_tcp.c,v 1.5 2007/01/08 13:37:26 reyk Exp $ */
/*
* Copyright (c) 2006 Pierre-Yves Ritschard <pyr@spootnik.org>
@@ -29,6 +29,7 @@
#include <string.h>
#include <stdlib.h>
#include <errno.h>
+#include <regex.h>
#include "hostated.h"
@@ -118,6 +119,8 @@ tcp_write(int s, short event, void *arg)
void
tcp_host_up(int s, struct ctl_tcp_event *cte)
{
+ cte->s = s;
+
switch (cte->table->check) {
case CHECK_TCP:
close(s);
@@ -127,6 +130,9 @@ tcp_host_up(int s, struct ctl_tcp_event *cte)
case CHECK_HTTP_DIGEST:
send_http_request(cte);
break;
+ case CHECK_SEND_EXPECT:
+ start_send_expect(cte);
+ break;
default:
fatalx("tcp_write: unhandled check type");
}
diff --git a/usr.sbin/hostated/control.c b/usr.sbin/hostated/control.c
index 4f58a7654e3..1266b9fd21f 100644
--- a/usr.sbin/hostated/control.c
+++ b/usr.sbin/hostated/control.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: control.c,v 1.4 2006/12/16 18:50:33 reyk Exp $ */
+/* $OpenBSD: control.c,v 1.5 2007/01/08 13:37:26 reyk Exp $ */
/*
* Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
@@ -30,6 +30,7 @@
#include <string.h>
#include <unistd.h>
#include <signal.h>
+#include <regex.h>
#include "hostated.h"
diff --git a/usr.sbin/hostated/hce.c b/usr.sbin/hostated/hce.c
index 6b291036e17..21cfe8a91aa 100644
--- a/usr.sbin/hostated/hce.c
+++ b/usr.sbin/hostated/hce.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: hce.c,v 1.4 2006/12/25 18:12:14 reyk Exp $ */
+/* $OpenBSD: hce.c,v 1.5 2007/01/08 13:37:26 reyk Exp $ */
/*
* Copyright (c) 2006 Pierre-Yves Ritschard <pyr@spootnik.org>
@@ -35,6 +35,7 @@
#include <unistd.h>
#include <err.h>
#include <pwd.h>
+#include <regex.h>
#include "hostated.h"
diff --git a/usr.sbin/hostated/hostated.c b/usr.sbin/hostated/hostated.c
index e1adfb3628a..8d2abc6e7cc 100644
--- a/usr.sbin/hostated/hostated.c
+++ b/usr.sbin/hostated/hostated.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: hostated.c,v 1.5 2006/12/25 18:40:38 reyk Exp $ */
+/* $OpenBSD: hostated.c,v 1.6 2007/01/08 13:37:26 reyk Exp $ */
/*
* Copyright (c) 2006 Pierre-Yves Ritschard <pyr@spootnik.org>
@@ -32,6 +32,7 @@
#include <signal.h>
#include <unistd.h>
#include <pwd.h>
+#include <regex.h>
#include "hostated.h"
diff --git a/usr.sbin/hostated/hostated.conf.5 b/usr.sbin/hostated/hostated.conf.5
index f0985ede244..31c8cbc3f1d 100644
--- a/usr.sbin/hostated/hostated.conf.5
+++ b/usr.sbin/hostated/hostated.conf.5
@@ -1,4 +1,4 @@
-.\" $OpenBSD: hostated.conf.5,v 1.8 2007/01/03 09:42:30 reyk Exp $
+.\" $OpenBSD: hostated.conf.5,v 1.9 2007/01/08 13:37:26 reyk Exp $
.\"
.\" Copyright (c) 2006 Pierre-Yves Ritschard <pyr@spootnik.org>
.\"
@@ -115,6 +115,21 @@ a9993e36476816aba3e25717850c26c9cd0d89d
Ping hosts in this table to determine whether they are up or not.
This method will automatically use ICMP or ICMPV6 depending on the
address family of each host.
+.It Ic check send Ar data Ic expect Ar regexp
+For each host in the table, a TCP connection is established on the
+port specified, then
+.Ar data
+is sent.
+Incoming data is then read and is expected to match against
+.Ar regexp.
+If
+.Ar data
+is an empty string or
+.Ic nothing
+then nothing is sent on the connection and data is immediately
+read.
+This can be useful with protocols that output a banner like
+SMTP, NNTP and FTP.
.It Ic check tcp
Use a simple TCP connect to check that hosts are up.
.It Ic disable
diff --git a/usr.sbin/hostated/hostated.h b/usr.sbin/hostated/hostated.h
index 03338b90519..75ca9878c92 100644
--- a/usr.sbin/hostated/hostated.h
+++ b/usr.sbin/hostated/hostated.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: hostated.h,v 1.8 2007/01/03 09:45:29 reyk Exp $ */
+/* $OpenBSD: hostated.h,v 1.9 2007/01/08 13:37:26 reyk Exp $ */
/*
* Copyright (c) 2006 Pierre-Yves Ritschard <pyr@spootnik.org>
@@ -190,8 +190,11 @@ struct table {
struct timeval timeout;
char name[TABLE_NAME_SIZE];
char path[MAXPATHLEN];
+ char sendbuf[64];
+ char exbuf[64];
char digest[41]; /* length of sha1 digest * 2 */
struct hostlist hosts;
+ regex_t regx;
TAILQ_ENTRY(table) entry;
};
TAILQ_HEAD(tablelist, table);
@@ -201,6 +204,7 @@ TAILQ_HEAD(tablelist, table);
#define CHECK_TCP 2
#define CHECK_HTTP_CODE 3
#define CHECK_HTTP_DIGEST 4
+#define CHECK_SEND_EXPECT 5
struct service {
objid_t id;
@@ -339,6 +343,9 @@ void check_tcp(struct ctl_tcp_event *);
/* check_http.c */
void send_http_request(struct ctl_tcp_event *);
+/* check_send_expect.c */
+void start_send_expect(struct ctl_tcp_event *);
+
/* hostated.c */
struct host *host_find(struct hostated *, objid_t);
struct table *table_find(struct hostated *, objid_t);
diff --git a/usr.sbin/hostated/imsg.c b/usr.sbin/hostated/imsg.c
index feafd8700c1..13f136176a8 100644
--- a/usr.sbin/hostated/imsg.c
+++ b/usr.sbin/hostated/imsg.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: imsg.c,v 1.1 2006/12/16 11:45:07 reyk Exp $ */
+/* $OpenBSD: imsg.c,v 1.2 2007/01/08 13:37:26 reyk Exp $ */
/*
* Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
@@ -27,6 +27,7 @@
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
+#include <regex.h>
#include "hostated.h"
diff --git a/usr.sbin/hostated/parse.y b/usr.sbin/hostated/parse.y
index c50e5708cfa..3cb95466a72 100644
--- a/usr.sbin/hostated/parse.y
+++ b/usr.sbin/hostated/parse.y
@@ -1,4 +1,4 @@
-/* $OpenBSD: parse.y,v 1.8 2007/01/03 09:45:29 reyk Exp $ */
+/* $OpenBSD: parse.y,v 1.9 2007/01/08 13:37:26 reyk Exp $ */
/*
* Copyright (c) 2006 Pierre-Yves Ritschard <pyr@spootnik.org>
@@ -40,6 +40,7 @@
#include <stdio.h>
#include <netdb.h>
#include <string.h>
+#include <regex.h>
#include "hostated.h"
@@ -101,6 +102,7 @@ typedef struct {
%token CHECK HTTP HTTPS TCP ICMP EXTERNAL
%token TIMEOUT CODE DIGEST PORT TAG INTERFACE
%token VIRTUAL IP INTERVAL DISABLE STICKYADDR
+%token SEND EXPECT NOTHING
%token ERROR
%token <v.string> STRING
%type <v.string> interface
@@ -141,6 +143,20 @@ varset : STRING '=' STRING {
}
;
+sendbuf : NOTHING {
+ bzero(table->sendbuf, sizeof(table->sendbuf));
+ }
+ | STRING {
+ if (strlcpy(table->sendbuf, $1, sizeof(table->sendbuf))
+ >= sizeof(table->sendbuf)) {
+ yyerror("yyparse: send buffer truncated");
+ free($1);
+ YYERROR;
+ }
+ free($1);
+ }
+ ;
+
main : INTERVAL number { conf->interval = $2; }
| TIMEOUT timeout {
bcopy(&$2, &conf->timeout, sizeof(struct timeval));
@@ -361,7 +377,7 @@ tableoptsl : host {
YYERROR;
}
if (strlcpy(table->digest, $5,
- sizeof(table->digest)) >= sizeof (table->digest)) {
+ sizeof(table->digest)) >= sizeof(table->digest)) {
yyerror("http digest truncated");
free($3);
free($5);
@@ -370,6 +386,21 @@ tableoptsl : host {
free($3);
free($5);
}
+ | CHECK SEND sendbuf EXPECT STRING {
+ int ret;
+ char ebuf[32];
+
+ table->check = CHECK_SEND_EXPECT;
+ ret = regcomp(&table->regx, $5, REG_EXTENDED|REG_NOSUB);
+ if (ret != 0) {
+ regerror(ret, &table->regx, ebuf, sizeof(ebuf));
+ yyerror("cannot compile expect regexp: %s",
+ ebuf);
+ free($5);
+ YYERROR;
+ }
+ free($5);
+ }
| REAL PORT number {
if ($3 < 1 || $3 >= USHRT_MAX) {
yyerror("invalid port number: %d", $3);
@@ -471,6 +502,7 @@ lookup(char *s)
{ "code", CODE },
{ "digest", DIGEST },
{ "disable", DISABLE },
+ { "expect", EXPECT },
{ "external", EXTERNAL },
{ "host", HOST },
{ "http", HTTP },
@@ -479,8 +511,10 @@ lookup(char *s)
{ "interface", INTERFACE },
{ "interval", INTERVAL },
{ "ip", IP },
+ { "nothing", NOTHING },
{ "port", PORT },
{ "real", REAL },
+ { "send", SEND },
{ "service", SERVICE },
{ "sticky-address", STICKYADDR },
{ "table", TABLE },
@@ -528,7 +562,13 @@ lgetc(FILE *f)
while ((c = getc(f)) == '\\') {
next = getc(f);
- if (next != '\n') {
+ if (next == 'n') {
+ c = '\n';
+ break;
+ } else if (next == 'r') {
+ c = '\r';
+ break;
+ } else if (next != '\n') {
c = next;
break;
}
diff --git a/usr.sbin/hostated/pfe.c b/usr.sbin/hostated/pfe.c
index a4575ad17bd..18bf664347f 100644
--- a/usr.sbin/hostated/pfe.c
+++ b/usr.sbin/hostated/pfe.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pfe.c,v 1.3 2006/12/16 18:50:33 reyk Exp $ */
+/* $OpenBSD: pfe.c,v 1.4 2007/01/08 13:37:26 reyk Exp $ */
/*
* Copyright (c) 2006 Pierre-Yves Ritschard <pyr@spootnik.org>
@@ -30,6 +30,7 @@
#include <string.h>
#include <unistd.h>
#include <pwd.h>
+#include <regex.h>
#include "hostated.h"
diff --git a/usr.sbin/hostated/pfe_filter.c b/usr.sbin/hostated/pfe_filter.c
index 53f52c06e2a..dba7980325e 100644
--- a/usr.sbin/hostated/pfe_filter.c
+++ b/usr.sbin/hostated/pfe_filter.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pfe_filter.c,v 1.4 2007/01/05 16:39:23 reyk Exp $ */
+/* $OpenBSD: pfe_filter.c,v 1.5 2007/01/08 13:37:26 reyk Exp $ */
/*
* Copyright (c) 2006 Pierre-Yves Ritschard <pyr@spootnik.org>
@@ -34,6 +34,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
+#include <regex.h>
#include "hostated.h"
diff --git a/usr.sbin/hoststated/Makefile b/usr.sbin/hoststated/Makefile
index c04e70f3036..16a06450a62 100644
--- a/usr.sbin/hoststated/Makefile
+++ b/usr.sbin/hoststated/Makefile
@@ -1,8 +1,9 @@
-# $OpenBSD: Makefile,v 1.1 2006/12/16 11:45:07 reyk Exp $
+# $OpenBSD: Makefile,v 1.2 2007/01/08 13:37:26 reyk Exp $
PROG= hostated
-SRCS= parse.y log.c control.c buffer.c imsg.c hostated.c \
- pfe.c pfe_filter.c hce.c check_icmp.c check_tcp.c check_http.c
+SRCS= parse.y log.c control.c buffer.c imsg.c hostated.c \
+ pfe.c pfe_filter.c hce.c \
+ check_icmp.c check_tcp.c check_http.c check_send_expect.c
MAN= hostated.8 hostated.conf.5
LDADD= -levent
diff --git a/usr.sbin/hoststated/buffer.c b/usr.sbin/hoststated/buffer.c
index 3abe27b1e62..547d65ed859 100644
--- a/usr.sbin/hoststated/buffer.c
+++ b/usr.sbin/hoststated/buffer.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: buffer.c,v 1.1 2006/12/16 11:45:07 reyk Exp $ */
+/* $OpenBSD: buffer.c,v 1.2 2007/01/08 13:37:26 reyk Exp $ */
/*
* Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
@@ -29,6 +29,7 @@
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
+#include <regex.h>
#include "hostated.h"
diff --git a/usr.sbin/hoststated/check_http.c b/usr.sbin/hoststated/check_http.c
index b081c1ce2fa..899a240f7dc 100644
--- a/usr.sbin/hoststated/check_http.c
+++ b/usr.sbin/hoststated/check_http.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: check_http.c,v 1.4 2006/12/25 19:05:41 reyk Exp $ */
+/* $OpenBSD: check_http.c,v 1.5 2007/01/08 13:37:26 reyk Exp $ */
/*
* Copyright (c) 2006 Pierre-Yves Ritschard <pyr@spootnik.org>
*
@@ -28,6 +28,7 @@
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
+#include <regex.h>
#include "hostated.h"
diff --git a/usr.sbin/hoststated/check_icmp.c b/usr.sbin/hoststated/check_icmp.c
index 2880d4f5e84..ae18a97cc88 100644
--- a/usr.sbin/hoststated/check_icmp.c
+++ b/usr.sbin/hoststated/check_icmp.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: check_icmp.c,v 1.5 2007/01/03 09:45:29 reyk Exp $ */
+/* $OpenBSD: check_icmp.c,v 1.6 2007/01/08 13:37:26 reyk Exp $ */
/*
* Copyright (c) 2006 Pierre-Yves Ritschard <pyr@spootnik.org>
@@ -33,6 +33,7 @@
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
+#include <regex.h>
#include "hostated.h"
diff --git a/usr.sbin/hoststated/check_send_expect.c b/usr.sbin/hoststated/check_send_expect.c
new file mode 100644
index 00000000000..0a1aa4c7db7
--- /dev/null
+++ b/usr.sbin/hoststated/check_send_expect.c
@@ -0,0 +1,141 @@
+/* $OpenBSD: check_send_expect.c,v 1.1 2007/01/08 13:37:26 reyk Exp $ */
+/*
+ * Copyright (c) 2006 Pierre-Yves Ritschard <pyr@spootnik.org>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <sys/types.h>
+#include <sys/queue.h>
+#include <sys/socket.h>
+#include <sys/param.h>
+#include <net/if.h>
+#include <limits.h>
+#include <event.h>
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <regex.h>
+
+#include "hostated.h"
+
+void se_validate(struct ctl_tcp_event *);
+void se_read(int, short, void *);
+
+void
+se_validate(struct ctl_tcp_event *cte)
+{
+ u_char *b;
+
+ /*
+ * ensure string is nul-terminated.
+ */
+ b = buf_reserve(cte->buf, 1);
+ if (b == NULL)
+ fatal("out of memory");
+ *b = '\0';
+ if (regexec(&cte->table->regx, cte->buf->buf, 0, NULL, 0) == 0)
+ cte->host->up = HOST_UP;
+ else
+ cte->host->up = HOST_DOWN;
+
+ /*
+ * go back to original position.
+ */
+ cte->buf->wpos--;
+}
+
+void
+se_read(int s, short event, void *arg)
+{
+ ssize_t br;
+ char rbuf[SMALL_READ_BUF_SIZE];
+ struct timeval tv;
+ struct timeval tv_now;
+ struct ctl_tcp_event *cte = arg;
+
+ if (event == EV_TIMEOUT) {
+ cte->host->up = HOST_DOWN;
+ buf_free(cte->buf);
+ hce_notify_done(cte->host, "se_read: timeout");
+ return;
+ }
+ br = read(s, rbuf, sizeof(rbuf));
+ log_debug("se_read: %d bytes read", br);
+ if (br == 0) {
+ cte->host->up = HOST_DOWN;
+ se_validate(cte);
+ buf_free(cte->buf);
+ hce_notify_done(cte->host, "se_read: connection closed");
+ } else if (br == -1) {
+ cte->host->up = HOST_DOWN;
+ buf_free(cte->buf);
+ hce_notify_done(cte->host, "se_read: read failed");
+ } else {
+ buf_add(cte->buf, rbuf, br);
+ bcopy(&cte->table->timeout, &tv, sizeof(tv));
+ if (gettimeofday(&tv_now, NULL))
+ fatal("se_read: gettimeofday");
+ timersub(&tv_now, &cte->tv_start, &tv_now);
+ timersub(&tv, &tv_now, &tv);
+ se_validate(cte);
+ if (cte->host->up == HOST_UP) {
+ buf_free(cte->buf);
+ hce_notify_done(cte->host, NULL);
+ } else
+ event_once(s, EV_READ|EV_TIMEOUT, se_read, cte, &tv);
+ }
+}
+
+void
+start_send_expect(struct ctl_tcp_event *cte)
+{
+ int bs;
+ int pos;
+ int len;
+ char *req;
+ struct timeval tv;
+ struct timeval tv_now;
+
+ req = cte->table->sendbuf;
+ pos = 0;
+ len = strlen(req);
+ if (len) {
+ do {
+ bs = write(cte->s, req + pos, len);
+ if (bs <= 0) {
+ log_warnx("send_se_data: cannot send");
+ cte->host->up = HOST_DOWN;
+ hce_notify_done(cte->host,
+ "start_send_expect: write");
+ return;
+ }
+ pos += bs;
+ len -= bs;
+ } while (len > 0);
+ }
+
+ if ((cte->buf = buf_dynamic(SMALL_READ_BUF_SIZE, UINT_MAX)) == NULL)
+ fatalx("send_se_data: cannot create dynamic buffer");
+
+ log_debug("start_send_expect: reading");
+
+ bcopy(&cte->table->timeout, &tv, sizeof(tv));
+ if (gettimeofday(&tv_now, NULL))
+ fatal("start_send_expect: gettimeofday");
+ timersub(&tv_now, &cte->tv_start, &tv_now);
+ timersub(&tv, &tv_now, &tv);
+ event_once(cte->s, EV_READ|EV_TIMEOUT, se_read, cte, &tv);
+}
diff --git a/usr.sbin/hoststated/check_tcp.c b/usr.sbin/hoststated/check_tcp.c
index 93cf8dd7041..888edb8da31 100644
--- a/usr.sbin/hoststated/check_tcp.c
+++ b/usr.sbin/hoststated/check_tcp.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: check_tcp.c,v 1.4 2006/12/25 19:05:41 reyk Exp $ */
+/* $OpenBSD: check_tcp.c,v 1.5 2007/01/08 13:37:26 reyk Exp $ */
/*
* Copyright (c) 2006 Pierre-Yves Ritschard <pyr@spootnik.org>
@@ -29,6 +29,7 @@
#include <string.h>
#include <stdlib.h>
#include <errno.h>
+#include <regex.h>
#include "hostated.h"
@@ -118,6 +119,8 @@ tcp_write(int s, short event, void *arg)
void
tcp_host_up(int s, struct ctl_tcp_event *cte)
{
+ cte->s = s;
+
switch (cte->table->check) {
case CHECK_TCP:
close(s);
@@ -127,6 +130,9 @@ tcp_host_up(int s, struct ctl_tcp_event *cte)
case CHECK_HTTP_DIGEST:
send_http_request(cte);
break;
+ case CHECK_SEND_EXPECT:
+ start_send_expect(cte);
+ break;
default:
fatalx("tcp_write: unhandled check type");
}
diff --git a/usr.sbin/hoststated/control.c b/usr.sbin/hoststated/control.c
index 4f58a7654e3..1266b9fd21f 100644
--- a/usr.sbin/hoststated/control.c
+++ b/usr.sbin/hoststated/control.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: control.c,v 1.4 2006/12/16 18:50:33 reyk Exp $ */
+/* $OpenBSD: control.c,v 1.5 2007/01/08 13:37:26 reyk Exp $ */
/*
* Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
@@ -30,6 +30,7 @@
#include <string.h>
#include <unistd.h>
#include <signal.h>
+#include <regex.h>
#include "hostated.h"
diff --git a/usr.sbin/hoststated/hce.c b/usr.sbin/hoststated/hce.c
index 6b291036e17..21cfe8a91aa 100644
--- a/usr.sbin/hoststated/hce.c
+++ b/usr.sbin/hoststated/hce.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: hce.c,v 1.4 2006/12/25 18:12:14 reyk Exp $ */
+/* $OpenBSD: hce.c,v 1.5 2007/01/08 13:37:26 reyk Exp $ */
/*
* Copyright (c) 2006 Pierre-Yves Ritschard <pyr@spootnik.org>
@@ -35,6 +35,7 @@
#include <unistd.h>
#include <err.h>
#include <pwd.h>
+#include <regex.h>
#include "hostated.h"
diff --git a/usr.sbin/hoststated/hoststated.c b/usr.sbin/hoststated/hoststated.c
index d1d8419c785..18d7a33bf71 100644
--- a/usr.sbin/hoststated/hoststated.c
+++ b/usr.sbin/hoststated/hoststated.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: hoststated.c,v 1.5 2006/12/25 18:40:38 reyk Exp $ */
+/* $OpenBSD: hoststated.c,v 1.6 2007/01/08 13:37:26 reyk Exp $ */
/*
* Copyright (c) 2006 Pierre-Yves Ritschard <pyr@spootnik.org>
@@ -32,6 +32,7 @@
#include <signal.h>
#include <unistd.h>
#include <pwd.h>
+#include <regex.h>
#include "hostated.h"
diff --git a/usr.sbin/hoststated/hoststated.conf.5 b/usr.sbin/hoststated/hoststated.conf.5
index 3a5e9a671a5..74d3b3d102a 100644
--- a/usr.sbin/hoststated/hoststated.conf.5
+++ b/usr.sbin/hoststated/hoststated.conf.5
@@ -1,4 +1,4 @@
-.\" $OpenBSD: hoststated.conf.5,v 1.8 2007/01/03 09:42:30 reyk Exp $
+.\" $OpenBSD: hoststated.conf.5,v 1.9 2007/01/08 13:37:26 reyk Exp $
.\"
.\" Copyright (c) 2006 Pierre-Yves Ritschard <pyr@spootnik.org>
.\"
@@ -115,6 +115,21 @@ a9993e36476816aba3e25717850c26c9cd0d89d
Ping hosts in this table to determine whether they are up or not.
This method will automatically use ICMP or ICMPV6 depending on the
address family of each host.
+.It Ic check send Ar data Ic expect Ar regexp
+For each host in the table, a TCP connection is established on the
+port specified, then
+.Ar data
+is sent.
+Incoming data is then read and is expected to match against
+.Ar regexp.
+If
+.Ar data
+is an empty string or
+.Ic nothing
+then nothing is sent on the connection and data is immediately
+read.
+This can be useful with protocols that output a banner like
+SMTP, NNTP and FTP.
.It Ic check tcp
Use a simple TCP connect to check that hosts are up.
.It Ic disable
diff --git a/usr.sbin/hoststated/hoststated.h b/usr.sbin/hoststated/hoststated.h
index f0d6839c4f5..f2555aa6270 100644
--- a/usr.sbin/hoststated/hoststated.h
+++ b/usr.sbin/hoststated/hoststated.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: hoststated.h,v 1.8 2007/01/03 09:45:29 reyk Exp $ */
+/* $OpenBSD: hoststated.h,v 1.9 2007/01/08 13:37:26 reyk Exp $ */
/*
* Copyright (c) 2006 Pierre-Yves Ritschard <pyr@spootnik.org>
@@ -190,8 +190,11 @@ struct table {
struct timeval timeout;
char name[TABLE_NAME_SIZE];
char path[MAXPATHLEN];
+ char sendbuf[64];
+ char exbuf[64];
char digest[41]; /* length of sha1 digest * 2 */
struct hostlist hosts;
+ regex_t regx;
TAILQ_ENTRY(table) entry;
};
TAILQ_HEAD(tablelist, table);
@@ -201,6 +204,7 @@ TAILQ_HEAD(tablelist, table);
#define CHECK_TCP 2
#define CHECK_HTTP_CODE 3
#define CHECK_HTTP_DIGEST 4
+#define CHECK_SEND_EXPECT 5
struct service {
objid_t id;
@@ -339,6 +343,9 @@ void check_tcp(struct ctl_tcp_event *);
/* check_http.c */
void send_http_request(struct ctl_tcp_event *);
+/* check_send_expect.c */
+void start_send_expect(struct ctl_tcp_event *);
+
/* hostated.c */
struct host *host_find(struct hostated *, objid_t);
struct table *table_find(struct hostated *, objid_t);
diff --git a/usr.sbin/hoststated/imsg.c b/usr.sbin/hoststated/imsg.c
index feafd8700c1..13f136176a8 100644
--- a/usr.sbin/hoststated/imsg.c
+++ b/usr.sbin/hoststated/imsg.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: imsg.c,v 1.1 2006/12/16 11:45:07 reyk Exp $ */
+/* $OpenBSD: imsg.c,v 1.2 2007/01/08 13:37:26 reyk Exp $ */
/*
* Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
@@ -27,6 +27,7 @@
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
+#include <regex.h>
#include "hostated.h"
diff --git a/usr.sbin/hoststated/parse.y b/usr.sbin/hoststated/parse.y
index c50e5708cfa..3cb95466a72 100644
--- a/usr.sbin/hoststated/parse.y
+++ b/usr.sbin/hoststated/parse.y
@@ -1,4 +1,4 @@
-/* $OpenBSD: parse.y,v 1.8 2007/01/03 09:45:29 reyk Exp $ */
+/* $OpenBSD: parse.y,v 1.9 2007/01/08 13:37:26 reyk Exp $ */
/*
* Copyright (c) 2006 Pierre-Yves Ritschard <pyr@spootnik.org>
@@ -40,6 +40,7 @@
#include <stdio.h>
#include <netdb.h>
#include <string.h>
+#include <regex.h>
#include "hostated.h"
@@ -101,6 +102,7 @@ typedef struct {
%token CHECK HTTP HTTPS TCP ICMP EXTERNAL
%token TIMEOUT CODE DIGEST PORT TAG INTERFACE
%token VIRTUAL IP INTERVAL DISABLE STICKYADDR
+%token SEND EXPECT NOTHING
%token ERROR
%token <v.string> STRING
%type <v.string> interface
@@ -141,6 +143,20 @@ varset : STRING '=' STRING {
}
;
+sendbuf : NOTHING {
+ bzero(table->sendbuf, sizeof(table->sendbuf));
+ }
+ | STRING {
+ if (strlcpy(table->sendbuf, $1, sizeof(table->sendbuf))
+ >= sizeof(table->sendbuf)) {
+ yyerror("yyparse: send buffer truncated");
+ free($1);
+ YYERROR;
+ }
+ free($1);
+ }
+ ;
+
main : INTERVAL number { conf->interval = $2; }
| TIMEOUT timeout {
bcopy(&$2, &conf->timeout, sizeof(struct timeval));
@@ -361,7 +377,7 @@ tableoptsl : host {
YYERROR;
}
if (strlcpy(table->digest, $5,
- sizeof(table->digest)) >= sizeof (table->digest)) {
+ sizeof(table->digest)) >= sizeof(table->digest)) {
yyerror("http digest truncated");
free($3);
free($5);
@@ -370,6 +386,21 @@ tableoptsl : host {
free($3);
free($5);
}
+ | CHECK SEND sendbuf EXPECT STRING {
+ int ret;
+ char ebuf[32];
+
+ table->check = CHECK_SEND_EXPECT;
+ ret = regcomp(&table->regx, $5, REG_EXTENDED|REG_NOSUB);
+ if (ret != 0) {
+ regerror(ret, &table->regx, ebuf, sizeof(ebuf));
+ yyerror("cannot compile expect regexp: %s",
+ ebuf);
+ free($5);
+ YYERROR;
+ }
+ free($5);
+ }
| REAL PORT number {
if ($3 < 1 || $3 >= USHRT_MAX) {
yyerror("invalid port number: %d", $3);
@@ -471,6 +502,7 @@ lookup(char *s)
{ "code", CODE },
{ "digest", DIGEST },
{ "disable", DISABLE },
+ { "expect", EXPECT },
{ "external", EXTERNAL },
{ "host", HOST },
{ "http", HTTP },
@@ -479,8 +511,10 @@ lookup(char *s)
{ "interface", INTERFACE },
{ "interval", INTERVAL },
{ "ip", IP },
+ { "nothing", NOTHING },
{ "port", PORT },
{ "real", REAL },
+ { "send", SEND },
{ "service", SERVICE },
{ "sticky-address", STICKYADDR },
{ "table", TABLE },
@@ -528,7 +562,13 @@ lgetc(FILE *f)
while ((c = getc(f)) == '\\') {
next = getc(f);
- if (next != '\n') {
+ if (next == 'n') {
+ c = '\n';
+ break;
+ } else if (next == 'r') {
+ c = '\r';
+ break;
+ } else if (next != '\n') {
c = next;
break;
}
diff --git a/usr.sbin/hoststated/pfe.c b/usr.sbin/hoststated/pfe.c
index a4575ad17bd..18bf664347f 100644
--- a/usr.sbin/hoststated/pfe.c
+++ b/usr.sbin/hoststated/pfe.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pfe.c,v 1.3 2006/12/16 18:50:33 reyk Exp $ */
+/* $OpenBSD: pfe.c,v 1.4 2007/01/08 13:37:26 reyk Exp $ */
/*
* Copyright (c) 2006 Pierre-Yves Ritschard <pyr@spootnik.org>
@@ -30,6 +30,7 @@
#include <string.h>
#include <unistd.h>
#include <pwd.h>
+#include <regex.h>
#include "hostated.h"
diff --git a/usr.sbin/hoststated/pfe_filter.c b/usr.sbin/hoststated/pfe_filter.c
index 53f52c06e2a..dba7980325e 100644
--- a/usr.sbin/hoststated/pfe_filter.c
+++ b/usr.sbin/hoststated/pfe_filter.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pfe_filter.c,v 1.4 2007/01/05 16:39:23 reyk Exp $ */
+/* $OpenBSD: pfe_filter.c,v 1.5 2007/01/08 13:37:26 reyk Exp $ */
/*
* Copyright (c) 2006 Pierre-Yves Ritschard <pyr@spootnik.org>
@@ -34,6 +34,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
+#include <regex.h>
#include "hostated.h"
diff --git a/usr.sbin/relayd/Makefile b/usr.sbin/relayd/Makefile
index c04e70f3036..16a06450a62 100644
--- a/usr.sbin/relayd/Makefile
+++ b/usr.sbin/relayd/Makefile
@@ -1,8 +1,9 @@
-# $OpenBSD: Makefile,v 1.1 2006/12/16 11:45:07 reyk Exp $
+# $OpenBSD: Makefile,v 1.2 2007/01/08 13:37:26 reyk Exp $
PROG= hostated
-SRCS= parse.y log.c control.c buffer.c imsg.c hostated.c \
- pfe.c pfe_filter.c hce.c check_icmp.c check_tcp.c check_http.c
+SRCS= parse.y log.c control.c buffer.c imsg.c hostated.c \
+ pfe.c pfe_filter.c hce.c \
+ check_icmp.c check_tcp.c check_http.c check_send_expect.c
MAN= hostated.8 hostated.conf.5
LDADD= -levent
diff --git a/usr.sbin/relayd/buffer.c b/usr.sbin/relayd/buffer.c
index 3abe27b1e62..547d65ed859 100644
--- a/usr.sbin/relayd/buffer.c
+++ b/usr.sbin/relayd/buffer.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: buffer.c,v 1.1 2006/12/16 11:45:07 reyk Exp $ */
+/* $OpenBSD: buffer.c,v 1.2 2007/01/08 13:37:26 reyk Exp $ */
/*
* Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
@@ -29,6 +29,7 @@
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
+#include <regex.h>
#include "hostated.h"
diff --git a/usr.sbin/relayd/check_icmp.c b/usr.sbin/relayd/check_icmp.c
index 2880d4f5e84..ae18a97cc88 100644
--- a/usr.sbin/relayd/check_icmp.c
+++ b/usr.sbin/relayd/check_icmp.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: check_icmp.c,v 1.5 2007/01/03 09:45:29 reyk Exp $ */
+/* $OpenBSD: check_icmp.c,v 1.6 2007/01/08 13:37:26 reyk Exp $ */
/*
* Copyright (c) 2006 Pierre-Yves Ritschard <pyr@spootnik.org>
@@ -33,6 +33,7 @@
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
+#include <regex.h>
#include "hostated.h"
diff --git a/usr.sbin/relayd/check_tcp.c b/usr.sbin/relayd/check_tcp.c
index 93cf8dd7041..888edb8da31 100644
--- a/usr.sbin/relayd/check_tcp.c
+++ b/usr.sbin/relayd/check_tcp.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: check_tcp.c,v 1.4 2006/12/25 19:05:41 reyk Exp $ */
+/* $OpenBSD: check_tcp.c,v 1.5 2007/01/08 13:37:26 reyk Exp $ */
/*
* Copyright (c) 2006 Pierre-Yves Ritschard <pyr@spootnik.org>
@@ -29,6 +29,7 @@
#include <string.h>
#include <stdlib.h>
#include <errno.h>
+#include <regex.h>
#include "hostated.h"
@@ -118,6 +119,8 @@ tcp_write(int s, short event, void *arg)
void
tcp_host_up(int s, struct ctl_tcp_event *cte)
{
+ cte->s = s;
+
switch (cte->table->check) {
case CHECK_TCP:
close(s);
@@ -127,6 +130,9 @@ tcp_host_up(int s, struct ctl_tcp_event *cte)
case CHECK_HTTP_DIGEST:
send_http_request(cte);
break;
+ case CHECK_SEND_EXPECT:
+ start_send_expect(cte);
+ break;
default:
fatalx("tcp_write: unhandled check type");
}
diff --git a/usr.sbin/relayd/control.c b/usr.sbin/relayd/control.c
index 4f58a7654e3..1266b9fd21f 100644
--- a/usr.sbin/relayd/control.c
+++ b/usr.sbin/relayd/control.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: control.c,v 1.4 2006/12/16 18:50:33 reyk Exp $ */
+/* $OpenBSD: control.c,v 1.5 2007/01/08 13:37:26 reyk Exp $ */
/*
* Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
@@ -30,6 +30,7 @@
#include <string.h>
#include <unistd.h>
#include <signal.h>
+#include <regex.h>
#include "hostated.h"
diff --git a/usr.sbin/relayd/hce.c b/usr.sbin/relayd/hce.c
index 6b291036e17..21cfe8a91aa 100644
--- a/usr.sbin/relayd/hce.c
+++ b/usr.sbin/relayd/hce.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: hce.c,v 1.4 2006/12/25 18:12:14 reyk Exp $ */
+/* $OpenBSD: hce.c,v 1.5 2007/01/08 13:37:26 reyk Exp $ */
/*
* Copyright (c) 2006 Pierre-Yves Ritschard <pyr@spootnik.org>
@@ -35,6 +35,7 @@
#include <unistd.h>
#include <err.h>
#include <pwd.h>
+#include <regex.h>
#include "hostated.h"
diff --git a/usr.sbin/relayd/imsg.c b/usr.sbin/relayd/imsg.c
index feafd8700c1..13f136176a8 100644
--- a/usr.sbin/relayd/imsg.c
+++ b/usr.sbin/relayd/imsg.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: imsg.c,v 1.1 2006/12/16 11:45:07 reyk Exp $ */
+/* $OpenBSD: imsg.c,v 1.2 2007/01/08 13:37:26 reyk Exp $ */
/*
* Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
@@ -27,6 +27,7 @@
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
+#include <regex.h>
#include "hostated.h"
diff --git a/usr.sbin/relayd/parse.y b/usr.sbin/relayd/parse.y
index c50e5708cfa..3cb95466a72 100644
--- a/usr.sbin/relayd/parse.y
+++ b/usr.sbin/relayd/parse.y
@@ -1,4 +1,4 @@
-/* $OpenBSD: parse.y,v 1.8 2007/01/03 09:45:29 reyk Exp $ */
+/* $OpenBSD: parse.y,v 1.9 2007/01/08 13:37:26 reyk Exp $ */
/*
* Copyright (c) 2006 Pierre-Yves Ritschard <pyr@spootnik.org>
@@ -40,6 +40,7 @@
#include <stdio.h>
#include <netdb.h>
#include <string.h>
+#include <regex.h>
#include "hostated.h"
@@ -101,6 +102,7 @@ typedef struct {
%token CHECK HTTP HTTPS TCP ICMP EXTERNAL
%token TIMEOUT CODE DIGEST PORT TAG INTERFACE
%token VIRTUAL IP INTERVAL DISABLE STICKYADDR
+%token SEND EXPECT NOTHING
%token ERROR
%token <v.string> STRING
%type <v.string> interface
@@ -141,6 +143,20 @@ varset : STRING '=' STRING {
}
;
+sendbuf : NOTHING {
+ bzero(table->sendbuf, sizeof(table->sendbuf));
+ }
+ | STRING {
+ if (strlcpy(table->sendbuf, $1, sizeof(table->sendbuf))
+ >= sizeof(table->sendbuf)) {
+ yyerror("yyparse: send buffer truncated");
+ free($1);
+ YYERROR;
+ }
+ free($1);
+ }
+ ;
+
main : INTERVAL number { conf->interval = $2; }
| TIMEOUT timeout {
bcopy(&$2, &conf->timeout, sizeof(struct timeval));
@@ -361,7 +377,7 @@ tableoptsl : host {
YYERROR;
}
if (strlcpy(table->digest, $5,
- sizeof(table->digest)) >= sizeof (table->digest)) {
+ sizeof(table->digest)) >= sizeof(table->digest)) {
yyerror("http digest truncated");
free($3);
free($5);
@@ -370,6 +386,21 @@ tableoptsl : host {
free($3);
free($5);
}
+ | CHECK SEND sendbuf EXPECT STRING {
+ int ret;
+ char ebuf[32];
+
+ table->check = CHECK_SEND_EXPECT;
+ ret = regcomp(&table->regx, $5, REG_EXTENDED|REG_NOSUB);
+ if (ret != 0) {
+ regerror(ret, &table->regx, ebuf, sizeof(ebuf));
+ yyerror("cannot compile expect regexp: %s",
+ ebuf);
+ free($5);
+ YYERROR;
+ }
+ free($5);
+ }
| REAL PORT number {
if ($3 < 1 || $3 >= USHRT_MAX) {
yyerror("invalid port number: %d", $3);
@@ -471,6 +502,7 @@ lookup(char *s)
{ "code", CODE },
{ "digest", DIGEST },
{ "disable", DISABLE },
+ { "expect", EXPECT },
{ "external", EXTERNAL },
{ "host", HOST },
{ "http", HTTP },
@@ -479,8 +511,10 @@ lookup(char *s)
{ "interface", INTERFACE },
{ "interval", INTERVAL },
{ "ip", IP },
+ { "nothing", NOTHING },
{ "port", PORT },
{ "real", REAL },
+ { "send", SEND },
{ "service", SERVICE },
{ "sticky-address", STICKYADDR },
{ "table", TABLE },
@@ -528,7 +562,13 @@ lgetc(FILE *f)
while ((c = getc(f)) == '\\') {
next = getc(f);
- if (next != '\n') {
+ if (next == 'n') {
+ c = '\n';
+ break;
+ } else if (next == 'r') {
+ c = '\r';
+ break;
+ } else if (next != '\n') {
c = next;
break;
}
diff --git a/usr.sbin/relayd/pfe.c b/usr.sbin/relayd/pfe.c
index a4575ad17bd..18bf664347f 100644
--- a/usr.sbin/relayd/pfe.c
+++ b/usr.sbin/relayd/pfe.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pfe.c,v 1.3 2006/12/16 18:50:33 reyk Exp $ */
+/* $OpenBSD: pfe.c,v 1.4 2007/01/08 13:37:26 reyk Exp $ */
/*
* Copyright (c) 2006 Pierre-Yves Ritschard <pyr@spootnik.org>
@@ -30,6 +30,7 @@
#include <string.h>
#include <unistd.h>
#include <pwd.h>
+#include <regex.h>
#include "hostated.h"
diff --git a/usr.sbin/relayd/pfe_filter.c b/usr.sbin/relayd/pfe_filter.c
index 53f52c06e2a..dba7980325e 100644
--- a/usr.sbin/relayd/pfe_filter.c
+++ b/usr.sbin/relayd/pfe_filter.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pfe_filter.c,v 1.4 2007/01/05 16:39:23 reyk Exp $ */
+/* $OpenBSD: pfe_filter.c,v 1.5 2007/01/08 13:37:26 reyk Exp $ */
/*
* Copyright (c) 2006 Pierre-Yves Ritschard <pyr@spootnik.org>
@@ -34,6 +34,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
+#include <regex.h>
#include "hostated.h"
diff --git a/usr.sbin/relayd/relayd.c b/usr.sbin/relayd/relayd.c
index 90648bfc898..ef75a4c755e 100644
--- a/usr.sbin/relayd/relayd.c
+++ b/usr.sbin/relayd/relayd.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: relayd.c,v 1.5 2006/12/25 18:40:38 reyk Exp $ */
+/* $OpenBSD: relayd.c,v 1.6 2007/01/08 13:37:26 reyk Exp $ */
/*
* Copyright (c) 2006 Pierre-Yves Ritschard <pyr@spootnik.org>
@@ -32,6 +32,7 @@
#include <signal.h>
#include <unistd.h>
#include <pwd.h>
+#include <regex.h>
#include "hostated.h"
diff --git a/usr.sbin/relayd/relayd.conf.5 b/usr.sbin/relayd/relayd.conf.5
index 48c805c0b2c..8445a43ef08 100644
--- a/usr.sbin/relayd/relayd.conf.5
+++ b/usr.sbin/relayd/relayd.conf.5
@@ -1,4 +1,4 @@
-.\" $OpenBSD: relayd.conf.5,v 1.8 2007/01/03 09:42:30 reyk Exp $
+.\" $OpenBSD: relayd.conf.5,v 1.9 2007/01/08 13:37:26 reyk Exp $
.\"
.\" Copyright (c) 2006 Pierre-Yves Ritschard <pyr@spootnik.org>
.\"
@@ -115,6 +115,21 @@ a9993e36476816aba3e25717850c26c9cd0d89d
Ping hosts in this table to determine whether they are up or not.
This method will automatically use ICMP or ICMPV6 depending on the
address family of each host.
+.It Ic check send Ar data Ic expect Ar regexp
+For each host in the table, a TCP connection is established on the
+port specified, then
+.Ar data
+is sent.
+Incoming data is then read and is expected to match against
+.Ar regexp.
+If
+.Ar data
+is an empty string or
+.Ic nothing
+then nothing is sent on the connection and data is immediately
+read.
+This can be useful with protocols that output a banner like
+SMTP, NNTP and FTP.
.It Ic check tcp
Use a simple TCP connect to check that hosts are up.
.It Ic disable
diff --git a/usr.sbin/relayd/relayd.h b/usr.sbin/relayd/relayd.h
index c8f02dc181f..f6dbe7bfc28 100644
--- a/usr.sbin/relayd/relayd.h
+++ b/usr.sbin/relayd/relayd.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: relayd.h,v 1.8 2007/01/03 09:45:29 reyk Exp $ */
+/* $OpenBSD: relayd.h,v 1.9 2007/01/08 13:37:26 reyk Exp $ */
/*
* Copyright (c) 2006 Pierre-Yves Ritschard <pyr@spootnik.org>
@@ -190,8 +190,11 @@ struct table {
struct timeval timeout;
char name[TABLE_NAME_SIZE];
char path[MAXPATHLEN];
+ char sendbuf[64];
+ char exbuf[64];
char digest[41]; /* length of sha1 digest * 2 */
struct hostlist hosts;
+ regex_t regx;
TAILQ_ENTRY(table) entry;
};
TAILQ_HEAD(tablelist, table);
@@ -201,6 +204,7 @@ TAILQ_HEAD(tablelist, table);
#define CHECK_TCP 2
#define CHECK_HTTP_CODE 3
#define CHECK_HTTP_DIGEST 4
+#define CHECK_SEND_EXPECT 5
struct service {
objid_t id;
@@ -339,6 +343,9 @@ void check_tcp(struct ctl_tcp_event *);
/* check_http.c */
void send_http_request(struct ctl_tcp_event *);
+/* check_send_expect.c */
+void start_send_expect(struct ctl_tcp_event *);
+
/* hostated.c */
struct host *host_find(struct hostated *, objid_t);
struct table *table_find(struct hostated *, objid_t);