diff options
author | Theo de Raadt <deraadt@cvs.openbsd.org> | 2007-01-09 00:44:38 +0000 |
---|---|---|
committer | Theo de Raadt <deraadt@cvs.openbsd.org> | 2007-01-09 00:44:38 +0000 |
commit | 0f21ce35a90163e1d34fde1138d534c719566ad8 (patch) | |
tree | 1d0b2380471d447d543e674323a255a487e25395 /usr.sbin | |
parent | 70c6dbc4dda674f526c605f7d16c595189152823 (diff) |
rename to hoststate{d,ctl}, using a repository copy
as discussed with reyk
Diffstat (limited to 'usr.sbin')
-rw-r--r-- | usr.sbin/hostatectl/Makefile | 16 | ||||
-rw-r--r-- | usr.sbin/hostatectl/hostatectl.8 | 77 | ||||
-rw-r--r-- | usr.sbin/hostatectl/hostatectl.c | 275 | ||||
-rw-r--r-- | usr.sbin/hostatectl/parser.c | 237 | ||||
-rw-r--r-- | usr.sbin/hostatectl/parser.h | 39 | ||||
-rw-r--r-- | usr.sbin/hostated/Makefile | 18 | ||||
-rw-r--r-- | usr.sbin/hostated/buffer.c | 222 | ||||
-rw-r--r-- | usr.sbin/hostated/check_http.c | 192 | ||||
-rw-r--r-- | usr.sbin/hostated/check_icmp.c | 394 | ||||
-rw-r--r-- | usr.sbin/hostated/check_send_expect.c | 141 | ||||
-rw-r--r-- | usr.sbin/hostated/check_tcp.c | 138 | ||||
-rw-r--r-- | usr.sbin/hostated/control.c | 340 | ||||
-rw-r--r-- | usr.sbin/hostated/hce.c | 358 | ||||
-rw-r--r-- | usr.sbin/hostated/hostated.8 | 96 | ||||
-rw-r--r-- | usr.sbin/hostated/hostated.c | 412 | ||||
-rw-r--r-- | usr.sbin/hostated/hostated.conf.5 | 264 | ||||
-rw-r--r-- | usr.sbin/hostated/hostated.h | 354 | ||||
-rw-r--r-- | usr.sbin/hostated/imsg.c | 181 | ||||
-rw-r--r-- | usr.sbin/hostated/log.c | 159 | ||||
-rw-r--r-- | usr.sbin/hostated/parse.y | 1023 | ||||
-rw-r--r-- | usr.sbin/hostated/pfe.c | 527 | ||||
-rw-r--r-- | usr.sbin/hostated/pfe_filter.c | 342 |
22 files changed, 0 insertions, 5805 deletions
diff --git a/usr.sbin/hostatectl/Makefile b/usr.sbin/hostatectl/Makefile deleted file mode 100644 index cf9a63acd8b..00000000000 --- a/usr.sbin/hostatectl/Makefile +++ /dev/null @@ -1,16 +0,0 @@ -# $OpenBSD: Makefile,v 1.1 2006/12/16 11:45:07 reyk Exp $ - -.PATH: ${.CURDIR}/../hostated - -PROG= hostatectl -SRCS= buffer.c imsg.c log.c hostatectl.c parser.c - -MAN= hostatectl.8 - -CFLAGS+= -Wall -Werror -I${.CURDIR} -I${.CURDIR}/../hostated -CFLAGS+= -Wstrict-prototypes -Wmissing-prototypes -CFLAGS+= -Wmissing-declarations -CFLAGS+= -Wshadow -Wpointer-arith -Wcast-qual -CFLAGS+= -Wsign-compare -Wbounded - -.include <bsd.prog.mk> diff --git a/usr.sbin/hostatectl/hostatectl.8 b/usr.sbin/hostatectl/hostatectl.8 deleted file mode 100644 index 6919a12887f..00000000000 --- a/usr.sbin/hostatectl/hostatectl.8 +++ /dev/null @@ -1,77 +0,0 @@ -.\" $OpenBSD: hostatectl.8,v 1.5 2006/12/19 14:44:38 jmc 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. -.\" -.Dd November 1, 2006 -.Dt HOSTATECTL 8 -.Os -.Sh NAME -.Nm hostatectl -.Nd control the host status daemon -.Sh SYNOPSIS -.Nm -.Ar command -.Op Ar arguments ... -.Sh DESCRIPTION -The -.Nm -program controls the -.Xr hostated 8 -daemon. -.Pp -The following commands are available: -.Bl -tag -width Ds -.It Cm host disable Op Ar name | id -Disable a host. -Treat it as though it were always down. -.It Cm host enable Op Ar name | id -Enable the host. -Start checking its health again. -.It Cm service disable Op Ar name | id -Disable a service. -If it has -.Xr pf 4 -redirection rules installed, remove them. -Mark the service's main table and \(en -if applicable \(en backup table disabled as well. -.It Cm service enable Op Ar name | id -Enable a service. -Mark the service's main table and \(en if applicable \(en backup -table enabled as well. -.It Cm show Op Cm summary -Show status of services, tables, and hosts. -The keyword -.Cm summary -is optional. -.It Cm table disable Op Ar name | id -Disable a table. -Consider all hosts disabled. -If it is a main table of a service which has a non-empty backup table, -swap the contents of the -.Xr pf 4 -table with those of the backup table. -.It Cm table enable Op Ar name | id -Enable a table. -Start doing checks for all hosts that aren't individually disabled -again. -.El -.Sh FILES -.Bl -tag -width "/var/run/hostated.sockXX" -compact -.It /var/run/hostated.sock -Unix-domain socket used for communication with -.Xr hostated 8 . -.El -.Sh SEE ALSO -.Xr hostated 8 diff --git a/usr.sbin/hostatectl/hostatectl.c b/usr.sbin/hostatectl/hostatectl.c deleted file mode 100644 index 740e72645e6..00000000000 --- a/usr.sbin/hostatectl/hostatectl.c +++ /dev/null @@ -1,275 +0,0 @@ -/* $OpenBSD: hostatectl.c,v 1.6 2006/12/16 18:50:33 reyk Exp $ */ - -/* - * Copyright (c) 2006 Pierre-Yves Ritschard <pyr@spootnik.org> - * Copyright (c) 2005 Claudio Jeker <claudio@openbsd.org> - * Copyright (c) 2004, 2005 Esben Norby <norby@openbsd.org> - * Copyright (c) 2003 Henning Brauer <henning@openbsd.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/socket.h> -#include <sys/queue.h> -#include <sys/un.h> -#include <netinet/in.h> -#include <arpa/inet.h> -#include <net/if.h> -#include <net/if_media.h> -#include <net/if_types.h> - -#include <err.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> -#include <event.h> - -#include "hostated.h" -#include "parser.h" - -__dead void usage(void); -int show_summary_msg(struct imsg *); -int show_command_output(struct imsg *); -char *print_service_status(int); -char *print_host_status(int, int); -char *print_table_status(int, int); - -struct imsgbuf *ibuf; - -__dead void -usage(void) -{ - extern char *__progname; - - fprintf(stderr, "usage: %s <command> [arg [...]]\n", __progname); - exit(1); -} - -/* dummy function so that hostatectl does not need libevent */ -void -imsg_event_add(struct imsgbuf *i) -{ - /* nothing */ -} - -int -main(int argc, char *argv[]) -{ - struct sockaddr_un sun; - struct parse_result *res; - struct imsg imsg; - int ctl_sock; - int done = 0; - int n; - - /* parse options */ - if ((res = parse(argc - 1, argv + 1)) == NULL) - exit(1); - - /* connect to hostated control socket */ - if ((ctl_sock = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) - err(1, "socket"); - - bzero(&sun, sizeof(sun)); - sun.sun_family = AF_UNIX; - strlcpy(sun.sun_path, HOSTATED_SOCKET, sizeof(sun.sun_path)); - if (connect(ctl_sock, (struct sockaddr *)&sun, sizeof(sun)) == -1) - err(1, "connect: %s", HOSTATED_SOCKET); - - if ((ibuf = malloc(sizeof(struct imsgbuf))) == NULL) - err(1, NULL); - imsg_init(ibuf, ctl_sock, NULL); - done = 0; - - /* process user request */ - switch (res->action) { - case NONE: - usage(); - /* not reached */ - case SHOW_SUM: - imsg_compose(ibuf, IMSG_CTL_SHOW_SUM, 0, 0, NULL, 0); - printf("Type\t%4s\t%-24s\tStatus\n", "Id", "Name"); - break; - case SERV_ENABLE: - imsg_compose(ibuf, IMSG_CTL_SERVICE_ENABLE, 0, 0, - &res->id, sizeof(res->id)); - break; - case SERV_DISABLE: - imsg_compose(ibuf, IMSG_CTL_SERVICE_DISABLE, 0, 0, - &res->id, sizeof(res->id)); - break; - case TABLE_ENABLE: - imsg_compose(ibuf, IMSG_CTL_TABLE_ENABLE, 0, 0, - &res->id, sizeof(res->id)); - break; - case TABLE_DISABLE: - imsg_compose(ibuf, IMSG_CTL_TABLE_DISABLE, 0, 0, - &res->id, sizeof(res->id)); - break; - case HOST_ENABLE: - imsg_compose(ibuf, IMSG_CTL_HOST_ENABLE, 0, 0, - &res->id, sizeof(res->id)); - break; - case HOST_DISABLE: - imsg_compose(ibuf, IMSG_CTL_HOST_DISABLE, 0, 0, - &res->id, sizeof(res->id)); - break; - case SHUTDOWN: - imsg_compose(ibuf, IMSG_CTL_SHUTDOWN, 0, 0, NULL, 0); - break; - case RELOAD: - imsg_compose(ibuf, IMSG_CTL_RELOAD, 0, 0, NULL, 0); - break; - } - - while (ibuf->w.queued) - if (msgbuf_write(&ibuf->w) < 0) - err(1, "write error"); - - while (!done) { - if ((n = imsg_read(ibuf)) == -1) - errx(1, "imsg_read error"); - if (n == 0) - errx(1, "pipe closed"); - - while (!done) { - if ((n = imsg_get(ibuf, &imsg)) == -1) - errx(1, "imsg_get error"); - if (n == 0) - break; - switch (res->action) { - case SHOW_SUM: - done = show_summary_msg(&imsg); - break; - case SERV_DISABLE: - case SERV_ENABLE: - case TABLE_DISABLE: - case TABLE_ENABLE: - case HOST_DISABLE: - case HOST_ENABLE: - done = show_command_output(&imsg); - break; - case RELOAD: - case SHUTDOWN: - case NONE: - break; - } - imsg_free(&imsg); - } - } - close(ctl_sock); - free(ibuf); - - return (0); -} - -int -show_summary_msg(struct imsg *imsg) -{ - struct service *service; - struct table *table; - struct host *host; - - switch (imsg->hdr.type) { - case IMSG_CTL_SERVICE: - service = imsg->data; - printf("service\t%4u\t%-24s\t%s\n", - service->id, service->name, - print_service_status(service->flags)); - break; - case IMSG_CTL_TABLE: - table = imsg->data; - printf("table\t%4u\t%-24s\t%s", - table->id, table->name, - print_table_status(table->up, table->flags)); - printf("\n"); - break; - case IMSG_CTL_HOST: - host = imsg->data; - printf("host\t%4u\t%-24s\t%s\n", - host->id, host->name, - print_host_status(host->up, host->flags)); - break; - case IMSG_CTL_END: - return (1); - default: - errx(1, "wrong message in summary: %u", imsg->hdr.type); - break; - } - return (0); -} - -int -show_command_output(struct imsg *imsg) -{ - switch (imsg->hdr.type) { - case IMSG_CTL_OK: - printf("command succeeded\n"); - break; - case IMSG_CTL_FAIL: - printf("command failed\n"); - break; - default: - errx(1, "wrong message in summary: %u", imsg->hdr.type); - } - return (1); -} - -char * -print_service_status(int flags) -{ - if (flags & F_DISABLE) { - return ("disabled"); - } else if (flags & F_DOWN) { - return ("down"); - } else if (flags & F_BACKUP) { - return ("active (using backup table)"); - } else - return ("active"); -} - -char * -print_table_status(int up, int fl) -{ - static char buf[1024]; - - bzero(buf, sizeof(buf)); - - if (fl & F_DISABLE) { - snprintf(buf, sizeof(buf) - 1, "disabled"); - } else if (!up) { - snprintf(buf, sizeof(buf) - 1, "empty"); - } else - snprintf(buf, sizeof(buf) - 1, "active (%d hosts up)", up); - return (buf); -} - -char * -print_host_status(int status, int fl) -{ - if (fl & F_DISABLE) - return ("disabled"); - - switch (status) { - case HOST_DOWN: - return ("down"); - case HOST_UNKNOWN: - return ("unknown"); - case HOST_UP: - return ("up"); - default: - errx(1, "invalid status: %d", status); - } -} diff --git a/usr.sbin/hostatectl/parser.c b/usr.sbin/hostatectl/parser.c deleted file mode 100644 index 43703a6622b..00000000000 --- a/usr.sbin/hostatectl/parser.c +++ /dev/null @@ -1,237 +0,0 @@ -/* $OpenBSD: parser.c,v 1.4 2006/12/16 18:50:33 reyk Exp $ */ - -/* - * Copyright (c) 2006 Pierre-Yves Ritschard <pyr@spootnik.org> - * Copyright (c) 2004 Esben Norby <norby@openbsd.org> - * Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.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/socket.h> -#include <sys/queue.h> -#include <netinet/in.h> -#include <net/if.h> -#include <arpa/inet.h> -#include <err.h> -#include <errno.h> -#include <limits.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <event.h> - -#include "hostated.h" - -#include "parser.h" - -enum token_type { - NOTOKEN, - ENDTOKEN, - HOSTID, - TABLEID, - SERVICEID, - KEYWORD -}; - -struct token { - enum token_type type; - const char *keyword; - int value; - const struct token *next; -}; - -static const struct token t_main[]; -static const struct token t_service[]; -static const struct token t_table[]; -static const struct token t_host[]; -static const struct token t_service_id[]; -static const struct token t_table_id[]; -static const struct token t_host_id[]; - -static const struct token t_main[] = { - {KEYWORD, "show", SHOW_SUM, NULL}, - {KEYWORD, "stop", SHUTDOWN, NULL}, - {KEYWORD, "service", NULL, t_service}, - {KEYWORD, "table", NULL, t_table}, - {KEYWORD, "host", NULL, t_host}, - {ENDTOKEN, "", NONE, NULL} -}; - -static const struct token t_service[] = { - {NOTOKEN, "", NONE, NULL}, - {KEYWORD, "disable", SERV_DISABLE, t_service_id}, - {KEYWORD, "enable", SERV_ENABLE, t_service_id}, - {ENDTOKEN, "", NONE, NULL} -}; - -static const struct token t_table[] = { - {NOTOKEN, "", NONE, NULL}, - {KEYWORD, "disable", TABLE_DISABLE, t_table_id}, - {KEYWORD, "enable", TABLE_ENABLE, t_table_id}, - {ENDTOKEN, "", NONE, NULL} -}; - -static const struct token t_host[] = { - {NOTOKEN, "", NONE, NULL}, - {KEYWORD, "disable", HOST_DISABLE, t_host_id}, - {KEYWORD, "enable", HOST_ENABLE, t_host_id}, - {ENDTOKEN, "", NONE, NULL} -}; - -static const struct token t_service_id[] = { - {SERVICEID, "", NONE, NULL}, - {ENDTOKEN, "", NONE, NULL} -}; - -static const struct token t_table_id[] = { - {TABLEID, "", NONE, NULL}, - {ENDTOKEN, "", NONE, NULL} -}; - -static const struct token t_host_id[] = { - {HOSTID, "", NONE, NULL}, - {ENDTOKEN, "", NONE, NULL} -}; - -static struct parse_result res; - -struct parse_result * -parse(int argc, char *argv[]) -{ - const struct token *table = t_main; - const struct token *match; - - bzero(&res, sizeof(res)); - - while (argc > 0) { - if ((match = match_token(argv[0], table)) == NULL) { - fprintf(stderr, "valid commands/args:\n"); - show_valid_args(table); - return (NULL); - } - - argc--; - argv++; - - if (match->type == NOTOKEN || match->next == NULL) - break; - - table = match->next; - } - - if (argc > 0) { - fprintf(stderr, "superfluous argument: %s\n", argv[0]); - return (NULL); - } - - return (&res); -} - -const struct token * -match_token(const char *word, const struct token table[]) -{ - u_int i, match; - const struct token *t = NULL; - const char *errstr; - - match = 0; - - for (i = 0; table[i].type != ENDTOKEN; i++) { - switch (table[i].type) { - case NOTOKEN: - if (word == NULL || strlen(word) == 0) { - match++; - t = &table[i]; - } - break; - case KEYWORD: - if (word != NULL && strncmp(word, table[i].keyword, - strlen(word)) == 0) { - match++; - t = &table[i]; - if (t->value) - res.action = t->value; - } - break; - case HOSTID: - res.id.id = strtonum(word, 0, UINT_MAX, &errstr); - if (errstr) { - strlcpy(res.id.name, word, sizeof(res.id.name)); - res.id.id = EMPTY_ID; - } - t = &table[i]; - match++; - break; - case TABLEID: - res.id.id = strtonum(word, 0, UINT_MAX, &errstr); - if (errstr) { - strlcpy(res.id.name, word, sizeof(res.id.name)); - res.id.id = EMPTY_ID; - } - t = &table[i]; - match++; - break; - case SERVICEID: - res.id.id = strtonum(word, 0, UINT_MAX, &errstr); - if (errstr) { - strlcpy(res.id.name, word, sizeof(res.id.name)); - res.id.id = EMPTY_ID; - } - t = &table[i]; - match++; - break; - case ENDTOKEN: - break; - } - } - - if (match != 1) { - if (match > 1) - fprintf(stderr, "ambiguous argument: %s\n", word); - if (match < 1) - fprintf(stderr, "unknown argument: %s\n", word); - return (NULL); - } - - return (t); -} - -void -show_valid_args(const struct token table[]) -{ - int i; - - for (i = 0; table[i].type != ENDTOKEN; i++) { - switch (table[i].type) { - case NOTOKEN: - fprintf(stderr, " <cr>\n"); - break; - case KEYWORD: - fprintf(stderr, " %s\n", table[i].keyword); - break; - case SERVICEID: - fprintf(stderr, " <serviceid>\n"); - break; - case TABLEID: - fprintf(stderr, " <tableid>\n"); - break; - case HOSTID: - fprintf(stderr, " <hostid>\n"); - break; - case ENDTOKEN: - break; - } - } -} diff --git a/usr.sbin/hostatectl/parser.h b/usr.sbin/hostatectl/parser.h deleted file mode 100644 index 1f1c8e879e1..00000000000 --- a/usr.sbin/hostatectl/parser.h +++ /dev/null @@ -1,39 +0,0 @@ -/* $OpenBSD: parser.h,v 1.2 2006/12/16 18:50:33 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. - */ - -enum actions { - NONE, - SHOW_SUM, - SERV_DISABLE, - SERV_ENABLE, - TABLE_DISABLE, - TABLE_ENABLE, - HOST_DISABLE, - HOST_ENABLE, - SHUTDOWN, - RELOAD -}; - -struct parse_result { - struct ctl_id id; - enum actions action; -}; - -struct parse_result *parse(int, char *[]); -const struct token *match_token(const char *, const struct token []); -void show_valid_args(const struct token []); diff --git a/usr.sbin/hostated/Makefile b/usr.sbin/hostated/Makefile deleted file mode 100644 index 16a06450a62..00000000000 --- a/usr.sbin/hostated/Makefile +++ /dev/null @@ -1,18 +0,0 @@ -# $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 check_send_expect.c -MAN= hostated.8 hostated.conf.5 - -LDADD= -levent -DPADD= ${LIBEVENT} -CFLAGS+= -Wall -Werror -I${.CURDIR} -CFLAGS+= -Wstrict-prototypes -Wmissing-prototypes -CFLAGS+= -Wmissing-declarations -CFLAGS+= -Wshadow -Wpointer-arith -Wcast-qual -CFLAGS+= -Wsign-compare -Wbounded -CLEANFILES+= y.tab.h - -.include <bsd.prog.mk> diff --git a/usr.sbin/hostated/buffer.c b/usr.sbin/hostated/buffer.c deleted file mode 100644 index 6f462a2d44f..00000000000 --- a/usr.sbin/hostated/buffer.c +++ /dev/null @@ -1,222 +0,0 @@ -/* $OpenBSD: buffer.c,v 1.3 2007/01/08 20:46:18 reyk Exp $ */ - -/* - * Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.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/uio.h> -#include <sys/param.h> -#include <net/if.h> -#include <errno.h> -#include <event.h> -#include <limits.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> - -#include "hostated.h" - -int buf_realloc(struct buf *, size_t); -void buf_enqueue(struct msgbuf *, struct buf *); -void buf_dequeue(struct msgbuf *, struct buf *); - -struct buf * -buf_open(size_t len) -{ - struct buf *buf; - - if ((buf = calloc(1, sizeof(struct buf))) == NULL) - return (NULL); - if ((buf->buf = malloc(len)) == NULL) { - free(buf); - return (NULL); - } - buf->size = buf->max = len; - - return (buf); -} - -struct buf * -buf_dynamic(size_t len, size_t max) -{ - struct buf *buf; - - if (max < len) - return (NULL); - - if ((buf = buf_open(len)) == NULL) - return (NULL); - - if (max > 0) - buf->max = max; - - return (buf); -} - -int -buf_realloc(struct buf *buf, size_t len) -{ - u_char *b; - - /* on static buffers max is eq size and so the following fails */ - if (buf->wpos + len > buf->max) { - errno = ENOMEM; - return (-1); - } - - b = realloc(buf->buf, buf->wpos + len); - if (b == NULL) - return (-1); - buf->buf = b; - buf->size = buf->wpos + len; - - return (0); -} - -int -buf_add(struct buf *buf, void *data, size_t len) -{ - if (buf->wpos + len > buf->size) - if (buf_realloc(buf, len) == -1) - return (-1); - - memcpy(buf->buf + buf->wpos, data, len); - buf->wpos += len; - return (0); -} - -void * -buf_reserve(struct buf *buf, size_t len) -{ - void *b; - - if (buf->wpos + len > buf->size) - if (buf_realloc(buf, len) == -1) - return (NULL); - - b = buf->buf + buf->wpos; - buf->wpos += len; - return (b); -} - -void * -buf_seek(struct buf *buf, size_t pos, size_t len) -{ - /* only allowed to seek in already written parts */ - if (pos + len > buf->wpos) - return (NULL); - - return (buf->buf + pos); -} - -int -buf_close(struct msgbuf *msgbuf, struct buf *buf) -{ - buf_enqueue(msgbuf, buf); - return (1); -} - -void -buf_free(struct buf *buf) -{ - free(buf->buf); - free(buf); -} - -void -msgbuf_init(struct msgbuf *msgbuf) -{ - msgbuf->queued = 0; - msgbuf->fd = -1; - TAILQ_INIT(&msgbuf->bufs); -} - -void -msgbuf_clear(struct msgbuf *msgbuf) -{ - struct buf *buf; - - while ((buf = TAILQ_FIRST(&msgbuf->bufs)) != NULL) - buf_dequeue(msgbuf, buf); -} - -int -msgbuf_write(struct msgbuf *msgbuf) -{ - struct iovec iov[IOV_MAX]; - struct buf *buf, *next; - int i = 0; - ssize_t n; - struct msghdr msg; - - bzero(&iov, sizeof(iov)); - bzero(&msg, sizeof(msg)); - TAILQ_FOREACH(buf, &msgbuf->bufs, entry) { - if (i >= IOV_MAX) - break; - iov[i].iov_base = buf->buf + buf->rpos; - iov[i].iov_len = buf->size - buf->rpos; - i++; - } - - msg.msg_iov = iov; - msg.msg_iovlen = i; - - if ((n = sendmsg(msgbuf->fd, &msg, 0)) == -1) { - if (errno == EAGAIN || errno == ENOBUFS || - errno == EINTR) /* try later */ - return (0); - else - return (-1); - } - - if (n == 0) { /* connection closed */ - errno = 0; - return (-2); - } - - for (buf = TAILQ_FIRST(&msgbuf->bufs); buf != NULL && n > 0; - buf = next) { - next = TAILQ_NEXT(buf, entry); - if (buf->rpos + n >= buf->size) { - n -= buf->size - buf->rpos; - buf_dequeue(msgbuf, buf); - } else { - buf->rpos += n; - n = 0; - } - } - - return (0); -} - -void -buf_enqueue(struct msgbuf *msgbuf, struct buf *buf) -{ - TAILQ_INSERT_TAIL(&msgbuf->bufs, buf, entry); - msgbuf->queued++; -} - -void -buf_dequeue(struct msgbuf *msgbuf, struct buf *buf) -{ - TAILQ_REMOVE(&msgbuf->bufs, buf, entry); - msgbuf->queued--; - buf_free(buf); -} diff --git a/usr.sbin/hostated/check_http.c b/usr.sbin/hostated/check_http.c deleted file mode 100644 index 1abc40d0059..00000000000 --- a/usr.sbin/hostated/check_http.c +++ /dev/null @@ -1,192 +0,0 @@ -/* $OpenBSD: check_http.c,v 1.6 2007/01/08 20:46:18 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 <sha1.h> -#include <limits.h> -#include <event.h> -#include <string.h> -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <fcntl.h> - -#include "hostated.h" - -void check_http_code(struct ctl_tcp_event *); -void check_http_digest(struct ctl_tcp_event *); -void http_read(int, short, void *); - -void -check_http_code(struct ctl_tcp_event *cte) -{ - char *head; - char scode[4]; - const char *estr; - int code; - - head = cte->buf->buf; - if (strncmp(head, "HTTP/1.1 ", strlen("HTTP/1.1 ")) && - strncmp(head, "HTTP/1.0 ", strlen("HTTP/1.0 "))) { - log_debug("check_http_code: cannot parse HTTP version"); - cte->host->up = HOST_DOWN; - return; - } - head += strlen("HTTP/1.1 "); - if (strlen(head) < 5) /* code + \r\n */ { - cte->host->up = HOST_DOWN; - return; - } - strlcpy(scode, head, sizeof(scode)); - code = strtonum(scode, 100, 999, &estr); - if (estr != NULL) { - log_debug("check_http_code: cannot parse HTTP code"); - cte->host->up = HOST_DOWN; - return; - } - if (code != cte->table->retcode) { - log_debug("check_http_code: invalid HTTP code returned"); - cte->host->up = HOST_DOWN; - } else - cte->host->up = HOST_UP; -} - -void -check_http_digest(struct ctl_tcp_event *cte) -{ - char *head; - char digest[(SHA1_DIGEST_LENGTH*2)+1]; - - head = cte->buf->buf; - if ((head = strstr(head, "\r\n\r\n")) == NULL) { - log_debug("check_http_digest: host %u no end of headers", - cte->host->id); - cte->host->up = HOST_DOWN; - return; - } - head += strlen("\r\n\r\n"); - SHA1Data(head, strlen(head), digest); - - if (strcmp(cte->table->digest, digest)) { - log_warnx("check_http_digest: wrong digest for host %u", - cte->host->id); - cte->host->up = HOST_DOWN; - } else - cte->host->up = HOST_UP; -} - -void -http_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, "http_read: timeout"); - return; - } - br = read(s, rbuf, sizeof(rbuf)); - if (br == 0) { - cte->host->up = HOST_DOWN; - switch (cte->table->check) { - case CHECK_HTTP_CODE: - check_http_code(cte); - break; - case CHECK_HTTP_DIGEST: - check_http_digest(cte); - break; - default: - fatalx("http_read: unhandled check type"); - } - buf_free(cte->buf); - hce_notify_done(cte->host, "http_read: connection closed"); - } else if (br == -1) { - cte->host->up = HOST_DOWN; - buf_free(cte->buf); - hce_notify_done(cte->host, "http_read: read failed"); - } else { - buf_add(cte->buf, rbuf, br); - bcopy(&cte->table->timeout, &tv, sizeof(tv)); - if (gettimeofday(&tv_now, NULL)) - fatal("send_http_request: gettimeofday"); - timersub(&tv_now, &cte->tv_start, &tv_now); - timersub(&tv, &tv_now, &tv); - event_once(s, EV_READ|EV_TIMEOUT, http_read, cte, &tv); - } -} - -void -send_http_request(struct ctl_tcp_event *cte) -{ - int bs; - int pos; - int len; - char *req; - struct timeval tv; - struct timeval tv_now; - - switch (cte->table->check) { - case CHECK_HTTP_CODE: - asprintf(&req, "HEAD %s HTTP/1.0\r\n\r\n", - cte->table->path); - break; - case CHECK_HTTP_DIGEST: - asprintf(&req, "GET %s HTTP/1.0\r\n\r\n", - cte->table->path); - break; - default: - fatalx("send_http_request: unhandled check type"); - } - if (req == NULL) - fatal("out of memory"); - pos = 0; - len = strlen(req); - /* - * write all at once for now. - */ - do { - bs = write(cte->s, req + pos, len); - if (bs <= 0) { - log_warnx("send_http_request: cannot send request"); - cte->host->up = HOST_DOWN; - hce_notify_done(cte->host, "send_http_request: write"); - free(req); - return; - } - pos += bs; - len -= bs; - } while (len > 0); - free(req); - if ((cte->buf = buf_dynamic(SMALL_READ_BUF_SIZE, UINT_MAX)) == NULL) - fatalx("send_http_request: cannot create dynamic buffer"); - - bcopy(&cte->table->timeout, &tv, sizeof(tv)); - if (gettimeofday(&tv_now, NULL)) - fatal("send_http_request: gettimeofday"); - timersub(&tv_now, &cte->tv_start, &tv_now); - timersub(&tv, &tv_now, &tv); - event_once(cte->s, EV_READ|EV_TIMEOUT, http_read, cte, &tv); -} diff --git a/usr.sbin/hostated/check_icmp.c b/usr.sbin/hostated/check_icmp.c deleted file mode 100644 index 52f5feb45c2..00000000000 --- a/usr.sbin/hostated/check_icmp.c +++ /dev/null @@ -1,394 +0,0 @@ -/* $OpenBSD: check_icmp.c,v 1.7 2007/01/08 20:46:18 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 <netinet/in_systm.h> -#include <netinet/in.h> -#include <netinet/ip.h> -#include <netinet/ip_icmp.h> -#include <netinet/icmp6.h> -#include <net/if.h> -#include <arpa/inet.h> -#include <limits.h> -#include <event.h> -#include <errno.h> -#include <unistd.h> -#include <string.h> -#include <stdlib.h> - -#include "hostated.h" - -int icmp6_checks_done(struct ctl_icmp_event *); -int icmp4_checks_done(struct ctl_icmp_event *); -void send_icmp6(struct ctl_icmp_event *, struct host *); -void send_icmp4(struct ctl_icmp_event *, struct host *); -void recv_icmp6(int, short, void *); -void recv_icmp4(int, short, void *); -int in_cksum(u_short *, int); - -void -schedule_icmp(struct ctl_icmp_event *cie, struct table *table) -{ - struct host *host; - - TAILQ_FOREACH(host, &table->hosts, entry) { - if (host->flags & F_DISABLE) - continue; - host->last_up = host->up; - host->flags &= ~F_CHECK_DONE; - if (((struct sockaddr *)&host->ss)->sa_family == AF_INET) { - send_icmp4(cie, host); - } else { - send_icmp6(cie, host); - } - } -} - -void -check_icmp(struct ctl_icmp_event *cie) -{ - struct timeval tv; - - if (gettimeofday(&cie->tv_start, NULL)) - fatal("check_icmp: gettimeofday"); - bcopy(&cie->env->timeout, &tv, sizeof(tv)); - if (cie->has_icmp4) - event_once(cie->icmp_sock, EV_READ|EV_TIMEOUT, - recv_icmp4, cie, &tv); - if (cie->has_icmp6) - event_once(cie->icmp6_sock, EV_READ|EV_TIMEOUT, - recv_icmp6, cie, &tv); -} - -int -icmp6_checks_done(struct ctl_icmp_event *cie) -{ - struct table *table; - struct host *host; - - TAILQ_FOREACH(table, &cie->env->tables, entry) { - if (table->flags & F_DISABLE || table->check != CHECK_ICMP) - continue; - TAILQ_FOREACH(host, &table->hosts, entry) { - if (((struct sockaddr *)&host->ss)->sa_family != - AF_INET6) - continue; - if (!(host->flags & F_CHECK_DONE)) - return (0); - } - } - return (1); -} - -int -icmp4_checks_done(struct ctl_icmp_event *cie) -{ - struct table *table; - struct host *host; - - TAILQ_FOREACH(table, &cie->env->tables, entry) { - if (table->flags & F_DISABLE || table->check != CHECK_ICMP) - continue; - TAILQ_FOREACH(host, &table->hosts, entry) { - if (((struct sockaddr *)&host->ss)->sa_family != - AF_INET) - continue; - if (!(host->flags & F_CHECK_DONE)) { - return (0); - } - } - } - return (1); -} - -void -send_icmp6(struct ctl_icmp_event *cie, struct host *host) -{ - struct sockaddr *to; - struct icmp6_hdr *icp; - ssize_t i; - int datalen = (64 - 8); - u_char packet[datalen]; - - cie->has_icmp6 = 1; - to = (struct sockaddr *)&host->ss; - bzero(&packet, sizeof(packet)); - icp = (struct icmp6_hdr *)packet; - icp->icmp6_type = ICMP6_ECHO_REQUEST; - icp->icmp6_code = 0; - icp->icmp6_seq = 1; - icp->icmp6_id = getpid() & 0xffff; - - memcpy((packet + sizeof(*icp)), &host->id, sizeof(host->id)); - - i = sendto(cie->icmp6_sock, packet, datalen + 8, 0, to, - sizeof(struct sockaddr_in6)); - if (i < 0 || i != datalen + 8) { - host->up = HOST_DOWN; - hce_notify_done(host, "send_icmp6: cannot send"); - return; - } -} - -void -send_icmp4(struct ctl_icmp_event *cie, struct host *host) -{ - struct sockaddr *to; - struct icmp *icp; - ssize_t i; - int datalen = (64 - 8); - u_char packet[datalen]; - - cie->has_icmp4 = 1; - to = (struct sockaddr *)&host->ss; - bzero(&packet, sizeof(packet)); - icp = (struct icmp *)packet; - icp->icmp_type = ICMP_ECHO; - icp->icmp_code = 0; - icp->icmp_seq = htons(1); - icp->icmp_id = htons(getpid() & 0xffff); - icp->icmp_cksum = 0; - - memcpy(icp->icmp_data, &host->id, sizeof(host->id)); - icp->icmp_cksum = in_cksum((u_short *)icp, datalen + 8); - - i = sendto(cie->icmp_sock, packet, datalen + 8, 0, to, - sizeof(struct sockaddr_in)); - if (i < 0 || i != datalen + 8) { - host->up = HOST_DOWN; - hce_notify_done(host, "send_icmp4: cannot send"); - } -} - -void -recv_icmp6(int s, short event, void *arg) -{ - struct ctl_icmp_event *cie = arg; - int datalen = (64 - 8); - u_char packet[datalen]; - socklen_t len; - struct sockaddr_storage ss; - struct icmp6_hdr *icp; - struct host *host; - struct table *table; - ssize_t i; - objid_t id; - struct timeval tv; - struct timeval tv_now; - - if (event == EV_TIMEOUT) { - /* - * mark all hosts which have not responded yet as down. - */ - TAILQ_FOREACH(table, &cie->env->tables, entry) { - if (table->check != CHECK_ICMP || - table->flags & F_DISABLE) - continue; - TAILQ_FOREACH(host, &table->hosts, entry) { - if (host->flags & F_DISABLE) - continue; - if (((struct sockaddr *)&host->ss)->sa_family - != AF_INET6) - continue; - if (!(host->flags & F_CHECK_DONE)) { - host->up = HOST_DOWN; - } - } - } - return; - } - bzero(&packet, sizeof(packet)); - bzero(&ss, sizeof(ss)); - len = sizeof(struct sockaddr_in6); - i = recvfrom(s, packet, datalen + 8, 0, (struct sockaddr *)&ss, &len); - if (i < 0 || i != datalen + 8) { - log_warn("recv_icmp6: did not receive valid ping"); - return; - } - icp = (struct icmp6_hdr *)(packet); - memcpy(&id, (packet + sizeof(*icp)), sizeof(id)); - host = host_find(cie->env, id); - if (host == NULL) - log_warn("recv_icmp6: ping for unknown host received"); - if (bcmp(&ss, &host->ss, len)) { - log_warnx("recv_icmp6: forged icmp packet ?"); - return; - } - if (icp->icmp6_id != (getpid() & 0xffff)) { - log_warnx("recv_icmp6: did not receive valid ident"); - host->up = HOST_DOWN; - } else - host->up = HOST_UP; - hce_notify_done(host, "recv_icmp6: final"); - if (icmp6_checks_done(cie)) - return; - if (gettimeofday(&tv_now, NULL)) - fatal("recv_icmp6: gettimeofday"); - bcopy(&cie->env->timeout, &tv, sizeof(tv)); - timersub(&tv_now, &cie->tv_start, &tv_now); - timersub(&tv, &tv_now, &tv); - event_once(cie->icmp6_sock, EV_READ|EV_TIMEOUT, recv_icmp6, cie, &tv); -} - -void -recv_icmp4(int s, short event, void *arg) -{ - int datalen = (64 - 8); - socklen_t len; - struct icmp *icp; - struct ctl_icmp_event *cie = arg; - u_char packet[datalen]; - struct host *host; - struct table *table; - ssize_t i; - objid_t id; - struct timeval tv; - struct timeval tv_now; - struct sockaddr_storage ss; - - if (event == EV_TIMEOUT) { - /* - * mark all hosts which have not responded yet as down. - */ - TAILQ_FOREACH(table, &cie->env->tables, entry) { - if (table->check != CHECK_ICMP || - table->flags & F_DISABLE) - continue; - TAILQ_FOREACH(host, &table->hosts, entry) { - if (host->flags & F_DISABLE) - continue; - if (((struct sockaddr *)&host->ss)->sa_family - != AF_INET) - continue; - if (!(host->flags & F_CHECK_DONE)) { - host->up = HOST_DOWN; - } - } - } - return; - } - - len = sizeof(struct sockaddr_in); - bzero(&packet, sizeof(packet)); - bzero(&ss, sizeof(ss)); - i = recvfrom(s, packet, datalen + 8, 0, (struct sockaddr *)&ss, &len); - if (i < 0 || i != (datalen + 8)) { - log_warn("recv_icmp4: did not receive valid ping"); - return; - } - - icp = (struct icmp *)(packet + sizeof(struct ip)); - memcpy(&id, icp->icmp_data, sizeof(id)); - host = host_find(cie->env, id); - if (host == NULL) { - log_warnx("recv_icmp4: received ping for unknown host"); - return; - } - if (bcmp(&ss, &host->ss, len)) { - log_warnx("recv_icmp4: forged icmp packet ?"); - return; - } - if (ntohs(icp->icmp_id) != (getpid() & 0xffff)) { - log_warnx("recv_icmp4: did not receive valid ident"); - host->up = HOST_DOWN; - } else - host->up = HOST_UP; - - host->flags |= F_CHECK_DONE; - if (icmp4_checks_done(cie)) { - hce_notify_done(host, "recv_icmp4: all done"); - return; - } - hce_notify_done(host, "recv_icmp4: host"); - - if (gettimeofday(&tv_now, NULL)) - fatal("recv_icmp4: gettimeofday"); - - bcopy(&cie->env->timeout, &tv, sizeof(tv)); - timersub(&tv_now, &cie->tv_start, &tv_now); - timersub(&tv, &tv_now, &tv); - event_once(cie->icmp_sock, EV_READ|EV_TIMEOUT, recv_icmp4, cie, &tv); -} - -/* in_cksum from ping.c -- - * Checksum routine for Internet Protocol family headers (C Version) - * - * Copyright (c) 1989, 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Mike Muuss. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ -int -in_cksum(u_short *addr, int len) -{ - int nleft = len; - u_short *w = addr; - int sum = 0; - u_short answer = 0; - - /* - * Our algorithm is simple, using a 32 bit accumulator (sum), we add - * sequential 16 bit words to it, and at the end, fold back all the - * carry bits from the top 16 bits into the lower 16 bits. - */ - while (nleft > 1) { - sum += *w++; - nleft -= 2; - } - - /* mop up an odd byte, if necessary */ - if (nleft == 1) { - *(u_char *)(&answer) = *(u_char *)w ; - sum += answer; - } - - /* add back carry outs from top 16 bits to low 16 bits */ - sum = (sum >> 16) + (sum & 0xffff); /* add hi 16 to low 16 */ - sum += (sum >> 16); /* add carry */ - answer = ~sum; /* truncate to 16 bits */ - - return (answer); -} diff --git a/usr.sbin/hostated/check_send_expect.c b/usr.sbin/hostated/check_send_expect.c deleted file mode 100644 index 16b14eeddd7..00000000000 --- a/usr.sbin/hostated/check_send_expect.c +++ /dev/null @@ -1,141 +0,0 @@ -/* $OpenBSD: check_send_expect.c,v 1.2 2007/01/08 20:46:18 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 <fnmatch.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 (fnmatch(cte->table->exbuf, cte->buf->buf, 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 deleted file mode 100644 index 2f11cfe1869..00000000000 --- a/usr.sbin/hostated/check_tcp.c +++ /dev/null @@ -1,138 +0,0 @@ -/* $OpenBSD: check_tcp.c,v 1.7 2007/01/08 20:46:18 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 <netinet/in.h> -#include <net/if.h> -#include <limits.h> -#include <event.h> -#include <fcntl.h> -#include <unistd.h> -#include <string.h> -#include <stdlib.h> -#include <errno.h> - -#include "hostated.h" - -void tcp_write(int, short, void *); -void tcp_host_up(int s, struct ctl_tcp_event *); - -void -check_tcp(struct ctl_tcp_event *cte) -{ - int s; - int type; - socklen_t len; - struct timeval tv; - struct linger lng; - - switch (cte->host->ss.ss_family) { - case AF_INET: - ((struct sockaddr_in *)&cte->host->ss)->sin_port = - cte->table->port; - break; - case AF_INET6: - ((struct sockaddr_in6 *)&cte->host->ss)->sin6_port = - cte->table->port; - break; - } - - len = ((struct sockaddr *)&cte->host->ss)->sa_len; - - if ((s = socket(cte->host->ss.ss_family, SOCK_STREAM, 0)) == -1) - goto bad; - - bzero(&lng, sizeof(lng)); - if (setsockopt(s, SOL_SOCKET, SO_LINGER, &lng, sizeof(lng)) == -1) - goto bad; - - type = 1; - if (setsockopt(s, SOL_SOCKET, SO_REUSEPORT, &type, sizeof(type)) == -1) - goto bad; - - if (fcntl(s, F_SETFL, O_NONBLOCK) == -1) - goto bad; - - if (connect(s, (struct sockaddr *)&cte->host->ss, len) == -1) { - if (errno != EINPROGRESS) - goto bad; - } else { - cte->host->up = HOST_UP; - tcp_host_up(s, cte); - return; - } - bcopy(&cte->table->timeout, &tv, sizeof(tv)); - event_once(s, EV_TIMEOUT|EV_WRITE, tcp_write, cte, &tv); - return; -bad: - close(s); - cte->host->up = HOST_DOWN; - hce_notify_done(cte->host, "check_tcp: cannot connect"); -} - -void -tcp_write(int s, short event, void *arg) -{ - struct ctl_tcp_event *cte = arg; - int err; - socklen_t len; - - if (event == EV_TIMEOUT) { - log_debug("tcp_write: connect timed out"); - cte->host->up = HOST_DOWN; - } else { - len = sizeof(err); - if (getsockopt(s, SOL_SOCKET, SO_ERROR, &err, &len)) - fatal("tcp_write: getsockopt"); - if (err) - cte->host->up = HOST_DOWN; - else - cte->host->up = HOST_UP; - } - if (cte->host->up == HOST_UP) - tcp_host_up(s, cte); - else { - close(s); - hce_notify_done(cte->host, "connect failed"); - } -} - -void -tcp_host_up(int s, struct ctl_tcp_event *cte) -{ - cte->s = s; - - switch (cte->table->check) { - case CHECK_TCP: - close(s); - hce_notify_done(cte->host, "tcp_write: success"); - break; - case CHECK_HTTP_CODE: - 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 deleted file mode 100644 index 2368ce43e27..00000000000 --- a/usr.sbin/hostated/control.c +++ /dev/null @@ -1,340 +0,0 @@ -/* $OpenBSD: control.c,v 1.6 2007/01/08 20:46:18 reyk Exp $ */ - -/* - * Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.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/queue.h> -#include <sys/param.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <sys/socket.h> -#include <sys/un.h> -#include <net/if.h> -#include <errno.h> -#include <event.h> -#include <fcntl.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> -#include <signal.h> - -#include "hostated.h" - -#define CONTROL_BACKLOG 5 - -struct ctl_connlist ctl_conns; - -int control_imsg_relay(struct imsg *imsg); - -struct ctl_conn *control_connbyfd(int); -struct ctl_conn *control_connbypid(pid_t); -void control_close(int); - -int -control_init(void) -{ - struct sockaddr_un sun; - int fd; - mode_t old_umask; - - if ((fd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) { - log_warn("control_init: socket"); - return (-1); - } - - bzero(&sun, sizeof(sun)); - sun.sun_family = AF_UNIX; - strlcpy(sun.sun_path, HOSTATED_SOCKET, sizeof(sun.sun_path)); - - if (unlink(HOSTATED_SOCKET) == -1) - if (errno != ENOENT) { - log_warn("control_init: unlink %s", HOSTATED_SOCKET); - close(fd); - return (-1); - } - - old_umask = umask(S_IXUSR|S_IXGRP|S_IWOTH|S_IROTH|S_IXOTH); - if (bind(fd, (struct sockaddr *)&sun, sizeof(sun)) == -1) { - log_warn("control_init: bind: %s", HOSTATED_SOCKET); - close(fd); - umask(old_umask); - return (-1); - } - umask(old_umask); - - if (chmod(HOSTATED_SOCKET, S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP) == -1) { - log_warn("control_init: chmod"); - close(fd); - (void)unlink(HOSTATED_SOCKET); - return (-1); - } - - session_socket_blockmode(fd, BM_NONBLOCK); - control_state.fd = fd; - - return (0); -} - -int -control_listen(void) -{ - - if (listen(control_state.fd, CONTROL_BACKLOG) == -1) { - log_warn("control_listen: listen"); - return (-1); - } - - event_set(&control_state.ev, control_state.fd, EV_READ | EV_PERSIST, - control_accept, NULL); - event_add(&control_state.ev, NULL); - - return (0); -} - -void -control_cleanup(void) -{ - - unlink(HOSTATED_SOCKET); -} - -/* ARGSUSED */ -void -control_accept(int listenfd, short event, void *arg) -{ - int connfd; - socklen_t len; - struct sockaddr_un sun; - struct ctl_conn *c; - - len = sizeof(sun); - if ((connfd = accept(listenfd, - (struct sockaddr *)&sun, &len)) == -1) { - if (errno != EWOULDBLOCK && errno != EINTR) - log_warn("control_accept"); - return; - } - - session_socket_blockmode(connfd, BM_NONBLOCK); - - if ((c = malloc(sizeof(struct ctl_conn))) == NULL) { - log_warn("control_accept"); - return; - } - - imsg_init(&c->ibuf, connfd, control_dispatch_imsg); - c->ibuf.events = EV_READ; - event_set(&c->ibuf.ev, c->ibuf.fd, c->ibuf.events, - c->ibuf.handler, &c->ibuf); - event_add(&c->ibuf.ev, NULL); - - TAILQ_INSERT_TAIL(&ctl_conns, c, entry); -} - -struct ctl_conn * -control_connbyfd(int fd) -{ - struct ctl_conn *c; - - for (c = TAILQ_FIRST(&ctl_conns); c != NULL && c->ibuf.fd != fd; - c = TAILQ_NEXT(c, entry)) - ; /* nothing */ - - return (c); -} - -struct ctl_conn * -control_connbypid(pid_t pid) -{ - struct ctl_conn *c; - - for (c = TAILQ_FIRST(&ctl_conns); c != NULL && c->ibuf.pid != pid; - c = TAILQ_NEXT(c, entry)) - ; /* nothing */ - - return (c); -} - -void -control_close(int fd) -{ - struct ctl_conn *c; - - if ((c = control_connbyfd(fd)) == NULL) - log_warn("control_close: fd %d: not found", fd); - - msgbuf_clear(&c->ibuf.w); - TAILQ_REMOVE(&ctl_conns, c, entry); - - event_del(&c->ibuf.ev); - close(c->ibuf.fd); - free(c); -} - -/* ARGSUSED */ -void -control_dispatch_imsg(int fd, short event, void *arg) -{ - struct ctl_conn *c; - struct imsg imsg; - struct ctl_id id; - int n; - - if ((c = control_connbyfd(fd)) == NULL) { - log_warn("control_dispatch_imsg: fd %d: not found", fd); - return; - } - - switch (event) { - case EV_READ: - if ((n = imsg_read(&c->ibuf)) <= 0) { - control_close(fd); - return; - } - break; - case EV_WRITE: - if (msgbuf_write(&c->ibuf.w) < 0) { - control_close(fd); - return; - } - imsg_event_add(&c->ibuf); - return; - default: - fatalx("unknown event"); - } - - for (;;) { - if ((n = imsg_get(&c->ibuf, &imsg)) == -1) { - control_close(fd); - return; - } - - if (n == 0) - break; - - switch (imsg.hdr.type) { - case IMSG_CTL_SHOW_SUM: - show(c); - break; - case IMSG_CTL_SERVICE_DISABLE: - if (imsg.hdr.len != IMSG_HEADER_SIZE + sizeof(id)) - fatalx("invalid imsg header len"); - memcpy(&id, imsg.data, sizeof(id)); - if (disable_service(c, &id)) - imsg_compose(&c->ibuf, IMSG_CTL_FAIL, 0, 0, - NULL, 0); - else - imsg_compose(&c->ibuf, IMSG_CTL_OK, 0, 0, - NULL, 0); - break; - case IMSG_CTL_SERVICE_ENABLE: - if (imsg.hdr.len != IMSG_HEADER_SIZE + sizeof(id)) - fatalx("invalid imsg header len"); - memcpy(&id, imsg.data, sizeof(id)); - if (enable_service(c, &id)) - imsg_compose(&c->ibuf, IMSG_CTL_FAIL, 0, 0, - NULL, 0); - else - imsg_compose(&c->ibuf, IMSG_CTL_OK, 0, 0, - NULL, 0); - break; - case IMSG_CTL_TABLE_DISABLE: - if (imsg.hdr.len != IMSG_HEADER_SIZE + sizeof(id)) - fatalx("invalid imsg header len"); - memcpy(&id, imsg.data, sizeof(id)); - if (disable_table(c, &id)) - imsg_compose(&c->ibuf, IMSG_CTL_FAIL, 0, 0, - NULL, 0); - else - imsg_compose(&c->ibuf, IMSG_CTL_OK, 0, 0, - NULL, 0); - break; - case IMSG_CTL_TABLE_ENABLE: - if (imsg.hdr.len != IMSG_HEADER_SIZE + sizeof(id)) - fatalx("invalid imsg header len"); - memcpy(&id, imsg.data, sizeof(id)); - if (enable_table(c, &id)) - imsg_compose(&c->ibuf, IMSG_CTL_FAIL, 0, 0, - NULL, 0); - else - imsg_compose(&c->ibuf, IMSG_CTL_OK, 0, 0, - NULL, 0); - break; - case IMSG_CTL_HOST_DISABLE: - if (imsg.hdr.len != IMSG_HEADER_SIZE + sizeof(id)) - fatalx("invalid imsg header len"); - memcpy(&id, imsg.data, sizeof(id)); - if (disable_host(c, &id)) - imsg_compose(&c->ibuf, IMSG_CTL_FAIL, 0, 0, - NULL, 0); - else - imsg_compose(&c->ibuf, IMSG_CTL_OK, 0, 0, - NULL, 0); - break; - case IMSG_CTL_HOST_ENABLE: - if (imsg.hdr.len != IMSG_HEADER_SIZE + sizeof(id)) - fatalx("invalid imsg header len"); - memcpy(&id, imsg.data, sizeof(id)); - if (enable_host(c, &id)) - imsg_compose(&c->ibuf, IMSG_CTL_FAIL, 0, 0, - NULL, 0); - else - imsg_compose(&c->ibuf, IMSG_CTL_OK, 0, 0, - NULL, 0); - break; - case IMSG_CTL_SHUTDOWN: - case IMSG_CTL_RELOAD: - imsg_compose(&c->ibuf, IMSG_CTL_FAIL, 0, 0, NULL, 0); - break; - default: - log_debug("control_dispatch_imsg: " - "error handling imsg %d", imsg.hdr.type); - break; - } - imsg_free(&imsg); - } - - imsg_event_add(&c->ibuf); -} - -int -control_imsg_relay(struct imsg *imsg) -{ - struct ctl_conn *c; - - if ((c = control_connbypid(imsg->hdr.pid)) == NULL) - return (0); - - return (imsg_compose(&c->ibuf, imsg->hdr.type, 0, imsg->hdr.pid, - imsg->data, imsg->hdr.len - IMSG_HEADER_SIZE)); -} - -void -session_socket_blockmode(int fd, enum blockmodes bm) -{ - int flags; - - if ((flags = fcntl(fd, F_GETFL, 0)) == -1) - fatal("fnctl F_GETFL"); - - if (bm == BM_NONBLOCK) - flags |= O_NONBLOCK; - else - flags &= ~O_NONBLOCK; - - if ((flags = fcntl(fd, F_SETFL, flags)) == -1) - fatal("fnctl F_SETFL"); -} diff --git a/usr.sbin/hostated/hce.c b/usr.sbin/hostated/hce.c deleted file mode 100644 index 065c7f316b5..00000000000 --- a/usr.sbin/hostated/hce.c +++ /dev/null @@ -1,358 +0,0 @@ -/* $OpenBSD: hce.c,v 1.7 2007/01/08 20:46:18 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/queue.h> -#include <sys/param.h> -#include <sys/types.h> -#include <sys/time.h> -#include <sys/stat.h> -#include <sys/socket.h> -#include <sys/un.h> -#include <netinet/in_systm.h> -#include <netinet/in.h> -#include <netinet/ip.h> -#include <net/if.h> -#include <errno.h> -#include <event.h> -#include <fcntl.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> -#include <err.h> -#include <pwd.h> - -#include "hostated.h" - -void hce_sig_handler(int sig, short, void *); -void hce_shutdown(void); -void hce_dispatch_imsg(int, short, void *); -void hce_dispatch_parent(int, short, void *); -void hce_launch_checks(int, short, void *); -int hce_checks_done(void); - -static struct hostated *env = NULL; -struct imsgbuf *ibuf_pfe; -struct imsgbuf *ibuf_main; - -void -hce_sig_handler(int sig, short event, void *arg) -{ - switch (sig) { - case SIGINT: - case SIGTERM: - hce_shutdown(); - default: - fatalx("hce_sig_handler: unexpected signal"); - } -} - -pid_t -hce(struct hostated *x_env, int pipe_parent2pfe[2], int pipe_parent2hce[2], - int pipe_pfe2hce[2]) -{ - pid_t pid; - struct passwd *pw; - struct timeval tv; - struct event ev_sigint; - struct event ev_sigterm; - - switch (pid = fork()) { - case -1: - fatal("hce: cannot fork"); - case 0: - break; - default: - return (pid); - } - - env = x_env; - - /* this is needed for icmp tests */ - if ((env->icmp_sock = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP)) < 0) - err(1, "socket"); - if ((env->icmp6_sock = socket(AF_INET6, SOCK_RAW, IPPROTO_ICMPV6)) < 0) - err(1, "socket"); - - if ((pw = getpwnam(HOSTATED_USER)) == NULL) - fatal("hce: getpwnam"); - - if (chroot(pw->pw_dir) == -1) - fatal("hce: chroot"); - if (chdir("/") == -1) - fatal("hce: chdir(\"/\")"); - - setproctitle("host check engine"); - hostated_process = PROC_HCE; - - if (setgroups(1, &pw->pw_gid) || - setresgid(pw->pw_gid, pw->pw_gid, pw->pw_gid) || - setresuid(pw->pw_uid, pw->pw_uid, pw->pw_uid)) - fatal("hce: can't drop privileges"); - - env->cie.icmp_sock = env->icmp_sock; - env->cie.icmp6_sock = env->icmp6_sock; - env->cie.env = env; - - event_init(); - - signal_set(&ev_sigint, SIGINT, hce_sig_handler, NULL); - signal_set(&ev_sigterm, SIGTERM, hce_sig_handler, NULL); - signal_add(&ev_sigint, NULL); - signal_add(&ev_sigterm, NULL); - - /* setup pipes */ - close(pipe_pfe2hce[1]); - close(pipe_parent2hce[0]); - close(pipe_parent2pfe[0]); - close(pipe_parent2pfe[1]); - - if ((ibuf_pfe = calloc(1, sizeof(struct imsgbuf))) == NULL || - (ibuf_main = calloc(1, sizeof(struct imsgbuf))) == NULL) - fatal("hce"); - imsg_init(ibuf_pfe, pipe_pfe2hce[0], hce_dispatch_imsg); - imsg_init(ibuf_main, pipe_parent2hce[1], hce_dispatch_parent); - - ibuf_pfe->events = EV_READ; - event_set(&ibuf_pfe->ev, ibuf_pfe->fd, ibuf_pfe->events, - ibuf_pfe->handler, ibuf_pfe); - event_add(&ibuf_pfe->ev, NULL); - - ibuf_main->events = EV_READ; - event_set(&ibuf_main->ev, ibuf_main->fd, ibuf_main->events, - ibuf_main->handler, ibuf_main); - event_add(&ibuf_main->ev, NULL); - - evtimer_set(&env->ev, hce_launch_checks, NULL); - bcopy(&env->interval, &tv, sizeof(tv)); - evtimer_add(&env->ev, &tv); - - hce_launch_checks(0, 0, NULL); - event_dispatch(); - - hce_shutdown(); - - return (0); -} - -void -hce_launch_checks(int fd, short event, void *arg) -{ - struct host *host; - struct table *table; - - TAILQ_FOREACH(table, &env->tables, entry) { - if (table->flags & F_DISABLE) - continue; - if (table->check == CHECK_NOCHECK) - fatalx("hce_launch_checks: unknown check type"); - if (table->check == CHECK_ICMP) { - schedule_icmp(&env->cie, table); - continue; - } - /* - * tcp type checks follow - */ - TAILQ_FOREACH(host, &table->hosts, entry) { - if (host->flags & F_DISABLE) - continue; - bzero(&host->cte, sizeof(host->cte)); - host->last_up = host->up; - host->cte.host = host; - host->cte.table = table; - if (gettimeofday(&host->cte.tv_start, NULL)) - fatal("hce_launch_checks: gettimeofday"); - check_tcp(&host->cte); - } - } - check_icmp(&env->cie); -} - -int -hce_checks_done() -{ - struct table *table; - struct host *host; - - TAILQ_FOREACH(table, &env->tables, entry) { - if (table->flags & F_DISABLE) - continue; - TAILQ_FOREACH(host, &table->hosts, entry) { - if (host->flags & F_DISABLE) - continue; - if (!(host->flags & F_CHECK_DONE)) - return (0); - } - } - return (1); -} - -void -hce_notify_done(struct host *host, const char *msg) -{ - struct ctl_status st; - struct timeval tv; - struct table *table; - - st.id = host->id; - st.up = host->up; - host->flags |= F_CHECK_DONE; - if (msg) - log_debug("hce_notify_done: %s", msg); - if (host->up != host->last_up) { - imsg_compose(ibuf_pfe, IMSG_HOST_STATUS, 0, 0, &st, sizeof(st)); - host->last_up = host->up; - } - /* - * check if everything is done, I see no other way than going - * through the tree for every host that calls this function. - */ - if (hce_checks_done()) { - /* - * notify pfe checks are done and schedule next check - */ - imsg_compose(ibuf_pfe, IMSG_SYNC, 0, 0, NULL, 0); - TAILQ_FOREACH(table, &env->tables, entry) { - TAILQ_FOREACH(host, &table->hosts, entry) - host->flags &= ~F_CHECK_DONE; - } - bcopy(&env->interval, &tv, sizeof(tv)); - evtimer_add(&env->ev, &tv); - bzero(&st, sizeof(st)); - } -} - -void -hce_shutdown(void) -{ - log_info("host check engine exiting"); - _exit(0); -} - -void -hce_dispatch_imsg(int fd, short event, void *ptr) -{ - struct imsgbuf *ibuf; - struct imsg imsg; - ssize_t n; - objid_t id; - struct host *host; - struct table *table; - - ibuf = ptr; - switch (event) { - case EV_READ: - if ((n = imsg_read(ibuf)) == -1) - fatal("hce_dispatch_imsg: imsg_read_error"); - if (n == 0) - fatalx("hce_dispatch_imsg: pipe closed"); - break; - case EV_WRITE: - if (msgbuf_write(&ibuf->w) == -1) - fatal("hce_dispatch_imsg: msgbuf_write"); - imsg_event_add(ibuf); - return; - default: - fatalx("hce_dispatch_imsg: unknown event"); - } - - for (;;) { - if ((n = imsg_get(ibuf, &imsg)) == -1) - fatal("hce_dispatch_imsg: imsg_read error"); - if (n == 0) - break; - - switch (imsg.hdr.type) { - case IMSG_HOST_DISABLE: - memcpy(&id, imsg.data, sizeof(id)); - if ((host = host_find(env, id)) == NULL) - fatalx("hce_dispatch_imsg: desynchronized"); - host->flags |= F_DISABLE; - host->up = HOST_UNKNOWN; - break; - case IMSG_HOST_ENABLE: - memcpy(&id, imsg.data, sizeof(id)); - if ((host = host_find(env, id)) == NULL) - fatalx("hce_dispatch_imsg: desynchronized"); - host->flags &= ~(F_DISABLE); - host->up = HOST_UNKNOWN; - break; - case IMSG_TABLE_DISABLE: - memcpy(&id, imsg.data, sizeof(id)); - if ((table = table_find(env, id)) == NULL) - fatalx("hce_dispatch_imsg: desynchronized"); - table->flags |= F_DISABLE; - TAILQ_FOREACH(host, &table->hosts, entry) - host->up = HOST_UNKNOWN; - break; - case IMSG_TABLE_ENABLE: - memcpy(&id, imsg.data, sizeof(id)); - if ((table = table_find(env, id)) == NULL) - fatalx("hce_dispatch_imsg: desynchronized"); - table->flags &= ~(F_DISABLE); - TAILQ_FOREACH(host, &table->hosts, entry) - host->up = HOST_UNKNOWN; - break; - default: - log_debug("hce_dispatch_msg: unexpected imsg %d", - imsg.hdr.type); - break; - } - imsg_free(&imsg); - } - imsg_event_add(ibuf); -} - -void -hce_dispatch_parent(int fd, short event, void * ptr) -{ - struct imsgbuf *ibuf; - struct imsg imsg; - ssize_t n; - - ibuf = ptr; - switch (event) { - case EV_READ: - if ((n = imsg_read(ibuf)) == -1) - fatal("hce_dispatch_parent: imsg_read error"); - if (n == 0) /* connection closed */ - fatalx("hce_dispatch_parent: pipe closed"); - break; - case EV_WRITE: - if (msgbuf_write(&ibuf->w) == -1) - fatal("hce_dispatch_parent: msgbuf_write"); - imsg_event_add(ibuf); - return; - default: - fatalx("hce_dispatch_parent: unknown event"); - } - - for (;;) { - if ((n = imsg_get(ibuf, &imsg)) == -1) - fatal("hce_dispatch_parent: imsg_read error"); - if (n == 0) - break; - - switch (imsg.hdr.type) { - default: - log_debug("hce_dispatch_parent: unexpected imsg %d", - imsg.hdr.type); - break; - } - imsg_free(&imsg); - } -} diff --git a/usr.sbin/hostated/hostated.8 b/usr.sbin/hostated/hostated.8 deleted file mode 100644 index df39ac4d429..00000000000 --- a/usr.sbin/hostated/hostated.8 +++ /dev/null @@ -1,96 +0,0 @@ -.\" $OpenBSD: hostated.8,v 1.4 2006/12/18 19:48:04 jmc Exp $ -.\" -.\" Copyright (c) 2006 Pierre-Yves Ritschard <pyr@openbsd.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. -.\" -.Dd November 1, 2006 -.Dt HOSTATED 8 -.Os -.Sh NAME -.Nm hostated -.Nd Host Status daemon -.Sh SYNOPSIS -.Nm -.Op Fl dnv -.Op Fl f Ar file -.Sh DESCRIPTION -.Nm -is the host status daemon for server load balancing. -Its main purpose is to keep -.Xr pf 4 -tables up to date -as well as any related pf rdr rules. -To communicate with pf, -.Nm -uses the anchor facility. -To enable -.Nm -to install rulesets through the anchor, -the following line is required in the NAT section of -.Xr pf.conf 5 : -.Bd -literal -offset indent -rdr-anchor "hostated/*" -.Ed -.Pp -.Nm -manipulates three data types: services, tables, and hosts. -Each service represents a -.Xr pf 4 -rdr rule. -A service contains at least one table and one virtual IP which are -used to create the proper rule. -Each table contains at least one host, and is mapped to a pf table. -Additionally a table can be backed up i.e. its content will be swapped -by the content of another table when it is empty. -This can be used to serve static content when a dynamic service goes down. -See -.Xr hostated.conf 5 -for a more detailed explanation of how to configure -.Nm . -.Pp -.Xr hostatectl 8 -can be used to enable or disable hosts, tables, and services as well -as showing the current status of each object. -.Pp -The options are as follows: -.Bl -tag -width Ds -.It Fl d -Do not daemonize. -If this option is specified, -.Nm -will run in the foreground and log to -.Em stderr . -.It Fl f Ar file -Specify an alternative configuration file. -The default is -.Pa /etc/hostated.conf . -.It Fl n -Configtest mode. -Only check the configuration file for validity. -.It Fl v -Produce more verbose output. -.El -.Sh FILES -.Bl -tag -width "/var/run/hostated.sockXX" -compact -.It /etc/hostated.conf -Default -.Nm -configuration file. -.It /var/run/hostated.sock -Unix-domain socket used for communication with -.Xr hostatectl 8 . -.El -.Sh SEE ALSO -.Xr hostated.conf 5 , -.Xr hostatectl 8 diff --git a/usr.sbin/hostated/hostated.c b/usr.sbin/hostated/hostated.c deleted file mode 100644 index 38c71dd12b3..00000000000 --- a/usr.sbin/hostated/hostated.c +++ /dev/null @@ -1,412 +0,0 @@ -/* $OpenBSD: hostated.c,v 1.7 2007/01/08 20:46:18 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 <sys/wait.h> -#include <net/if.h> -#include <string.h> -#include <stdio.h> -#include <stdlib.h> -#include <getopt.h> -#include <err.h> -#include <errno.h> -#include <event.h> -#include <signal.h> -#include <unistd.h> -#include <pwd.h> - -#include "hostated.h" - -__dead void usage(void); - -void main_sig_handler(int, short, void *); -void main_shutdown(void); -void main_dispatch_pfe(int, short, void *); -void main_dispatch_hce(int, short, void *); -int check_child(pid_t, const char *); - -int pipe_parent2pfe[2]; -int pipe_parent2hce[2]; -int pipe_pfe2hce[2]; - -struct imsgbuf *ibuf_pfe; -struct imsgbuf *ibuf_hce; - -pid_t pfe_pid = 0; -pid_t hce_pid = 0; - -void -main_sig_handler(int sig, short event, void *arg) -{ - int die = 0; - - switch (sig) { - case SIGTERM: - case SIGINT: - die = 1; - case SIGCHLD: - if (check_child(pfe_pid, "pf udpate engine")) { - pfe_pid = 0; - die = 1; - } - if (check_child(hce_pid, "host check engine")) { - hce_pid = 0; - die = 1; - } - if (die) - main_shutdown(); - break; - case SIGHUP: - /* reconfigure */ - break; - default: - fatalx("unexpected signal"); - } -} - -/* __dead is for lint */ -__dead void -usage(void) -{ - extern char *__progname; - - fprintf(stderr, "%s [-dnv] [-f file]\n", __progname); - exit(1); -} - -int -main(int argc, char *argv[]) -{ - int c; - int debug; - u_int32_t opts; - struct hostated env; - const char *conffile; - struct event ev_sigint; - struct event ev_sigterm; - struct event ev_sigchld; - struct event ev_sighup; - - opts = 0; - debug = 0; - conffile = CONF_FILE; - bzero(&env, sizeof (env)); - - for (;(c = getopt(argc, argv, "dnf:v")) != -1;) { - switch (c) { - case 'd': - debug = 1; - break; - case 'n': - opts |= HOSTATED_OPT_NOACTION; - break; - case 'f': - conffile = optarg; - break; - case 'v': - opts |= HOSTATED_OPT_VERBOSE; - break; - default: - usage(); - } - } - - log_init(debug); - - if (parse_config(&env, conffile, opts)) - exit(1); - - if (env.opts & HOSTATED_OPT_NOACTION) { - fprintf(stderr, "configuration OK\n"); - exit(0); - } - - if (geteuid()) - errx(1, "need root privileges"); - - if (getpwnam(HOSTATED_USER) == NULL) - errx(1, "unknown user %s", HOSTATED_USER); - - if (!debug) - daemon(1, 0); - - log_info("startup"); - - if (socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC, pipe_parent2pfe) == -1) - fatal("socketpair"); - if (socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC, pipe_parent2hce) == -1) - fatal("socketpair"); - if (socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC, pipe_pfe2hce) == -1) - fatal("socketpair"); - - session_socket_blockmode(pipe_parent2pfe[0], BM_NONBLOCK); - session_socket_blockmode(pipe_parent2pfe[1], BM_NONBLOCK); - session_socket_blockmode(pipe_parent2hce[0], BM_NONBLOCK); - session_socket_blockmode(pipe_parent2hce[1], BM_NONBLOCK); - session_socket_blockmode(pipe_pfe2hce[0], BM_NONBLOCK); - session_socket_blockmode(pipe_pfe2hce[1], BM_NONBLOCK); - - pfe_pid = pfe(&env, pipe_parent2pfe, pipe_parent2hce, pipe_pfe2hce); - hce_pid = hce(&env, pipe_parent2pfe, pipe_parent2hce, pipe_pfe2hce); - - setproctitle("parent"); - - event_init(); - - signal_set(&ev_sigint, SIGINT, main_sig_handler, NULL); - signal_set(&ev_sigterm, SIGTERM, main_sig_handler, NULL); - signal_set(&ev_sigchld, SIGCHLD, main_sig_handler, NULL); - signal_set(&ev_sighup, SIGHUP, main_sig_handler, NULL); - signal_add(&ev_sigint, NULL); - signal_add(&ev_sigterm, NULL); - signal_add(&ev_sigchld, NULL); - signal_add(&ev_sighup, NULL); - - close(pipe_parent2pfe[1]); - close(pipe_parent2hce[1]); - close(pipe_pfe2hce[0]); - close(pipe_pfe2hce[1]); - - if ((ibuf_pfe = calloc(1, sizeof(struct imsgbuf))) == NULL || - (ibuf_hce = calloc(1, sizeof(struct imsgbuf))) == NULL) - fatal(NULL); - - imsg_init(ibuf_pfe, pipe_parent2pfe[0], main_dispatch_pfe); - imsg_init(ibuf_hce, pipe_parent2hce[0], main_dispatch_hce); - - ibuf_pfe->events = EV_READ; - event_set(&ibuf_pfe->ev, ibuf_pfe->fd, ibuf_pfe->events, - ibuf_pfe->handler, ibuf_pfe); - event_add(&ibuf_pfe->ev, NULL); - - ibuf_hce->events = EV_READ; - event_set(&ibuf_hce->ev, ibuf_hce->fd, ibuf_hce->events, - ibuf_hce->handler, ibuf_hce); - event_add(&ibuf_hce->ev, NULL); - - event_dispatch(); - - return (0); -} - -void -main_shutdown(void) -{ - pid_t pid; - - if (pfe_pid) - kill(pfe_pid, SIGTERM); - if (hce_pid) - kill(hce_pid, SIGTERM); - - do { - if ((pid = wait(NULL)) == -1 && - errno != EINTR && errno != ECHILD) - fatal("wait"); - } while (pid != -1 || (pid == -1 && errno == EINTR)); - - control_cleanup(); - log_info("terminating"); - exit(0); -} - -int -check_child(pid_t pid, const char *pname) -{ - int status; - - if (waitpid(pid, &status, WNOHANG) > 0) { - if (WIFEXITED(status)) { - log_warnx("check_child: lost child: %s exited", pname); - return (1); - } - if (WIFSIGNALED(status)) { - log_warnx("check_child: lost child: %s terminated; " - "signal %d", pname, WTERMSIG(status)); - return (1); - } - } - - return (0); -} - -void -imsg_event_add(struct imsgbuf *ibuf) -{ - ibuf->events = EV_READ; - if (ibuf->w.queued) - ibuf->events |= EV_WRITE; - - event_del(&ibuf->ev); - event_set(&ibuf->ev, ibuf->fd, ibuf->events, ibuf->handler, ibuf); - event_add(&ibuf->ev, NULL); -} - -void -main_dispatch_pfe(int fd, short event, void *ptr) -{ - struct imsgbuf *ibuf; - struct imsg imsg; - ssize_t n; - - ibuf = ptr; - switch (event) { - case EV_READ: - if ((n = imsg_read(ibuf)) == -1) - fatal("imsg_read_error"); - if (n == 0) - fatalx("parent: pipe closed"); - break; - case EV_WRITE: - if (msgbuf_write(&ibuf->w) == -1) - fatal("msgbuf_write"); - imsg_event_add(ibuf); - return; - default: - fatalx("unknown event"); - } - - for (;;) { - if ((n = imsg_get(ibuf, &imsg)) == -1) - fatal("main_dispatch_pfe: imsg_read error"); - if (n == 0) - break; - - switch (imsg.hdr.type) { - default: - log_debug("main_dispatch_pfe: unexpected imsg %d", - imsg.hdr.type); - break; - } - imsg_free(&imsg); - } - imsg_event_add(ibuf); -} - -void -main_dispatch_hce(int fd, short event, void * ptr) -{ - struct imsgbuf *ibuf; - struct imsg imsg; - ssize_t n; - - ibuf = ptr; - switch (event) { - case EV_READ: - if ((n = imsg_read(ibuf)) == -1) - fatal("imsg_read error"); - if (n == 0) /* connection closed */ - fatalx("parent: pipe closed"); - break; - case EV_WRITE: - if (msgbuf_write(&ibuf->w) == -1) - fatal("msgbuf_write"); - imsg_event_add(ibuf); - return; - default: - fatalx("unknown event"); - } - - for (;;) { - if ((n = imsg_get(ibuf, &imsg)) == -1) - fatal("main_dispatch_hce: imsg_read error"); - if (n == 0) - break; - - switch (imsg.hdr.type) { - default: - log_debug("main_dispatch_hce: unexpected imsg %d", - imsg.hdr.type); - break; - } - imsg_free(&imsg); - } -} - -struct host * -host_find(struct hostated *env, objid_t id) -{ - struct table *table; - struct host *host; - - TAILQ_FOREACH(table, &env->tables, entry) - TAILQ_FOREACH(host, &table->hosts, entry) - if (host->id == id) - return (host); - return (NULL); -} - -struct table * -table_find(struct hostated *env, objid_t id) -{ - struct table *table; - - TAILQ_FOREACH(table, &env->tables, entry) - if (table->id == id) - return (table); - return (NULL); -} - -struct service * -service_find(struct hostated *env, objid_t id) -{ - struct service *service; - - TAILQ_FOREACH(service, &env->services, entry) - if (service->id == id) - return (service); - return (NULL); -} - -struct host * -host_findbyname(struct hostated *env, const char *name) -{ - struct table *table; - struct host *host; - - TAILQ_FOREACH(table, &env->tables, entry) - TAILQ_FOREACH(host, &table->hosts, entry) - if (strcmp(host->name, name) == 0) - return (host); - return (NULL); -} - -struct table * -table_findbyname(struct hostated *env, const char *name) -{ - struct table *table; - - TAILQ_FOREACH(table, &env->tables, entry) - if (strcmp(table->name, name) == 0) - return (table); - return (NULL); -} - -struct service * -service_findbyname(struct hostated *env, const char *name) -{ - struct service *service; - - TAILQ_FOREACH(service, &env->services, entry) - if (strcmp(service->name, name) == 0) - return (service); - return (NULL); -} diff --git a/usr.sbin/hostated/hostated.conf.5 b/usr.sbin/hostated/hostated.conf.5 deleted file mode 100644 index 15ef2a8e4bd..00000000000 --- a/usr.sbin/hostated/hostated.conf.5 +++ /dev/null @@ -1,264 +0,0 @@ -.\" $OpenBSD: hostated.conf.5,v 1.12 2007/01/08 20:46:18 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. -.\" -.Dd November 1, 2006 -.Dt HOSTATED.CONF 5 -.Os -.Sh NAME -.Nm hostated.conf -.Nd Host Status daemon configuration file -.Sh DESCRIPTION -.Nm -is the configuration file for the Host Status Daemon, -.Xr hostated 8 . -.Sh SECTIONS -.Nm -is divided into four main sections: -.Bl -tag -width xxxx -.It Sy Macros -User-defined variables may be defined and used later, simplifying the -configuration file. -.It Sy Global Configuration -Global settings for -.Xr hostated 8 . -.It Sy Tables -Table definitions describe the content of a -.Xr pf 4 -table and the method used for checking the health of the hosts -they contain. -.It Sy Services -Services will be translated to -.Xr pf 4 -rdr rules if their table or backup table have content. -.El -.Pp -Within the sections, -a host -.Ar address -can be either specified by IPv4 address, IPv6 address, or DNS host name. -A -.Ar port -can be either specified by number or by name. -The port name to number mappings are found in the file -.Pa /etc/services, -see -.Xr services 5 -for details. -.Sh MACROS -Macros can be defined that will later be expanded in context. -Macro names must start with a letter, and may contain letters, digits, -and underscores. -Macro names may not be reserved words (for example, -.Ic table , -.Ic service , -or -.Ic timeout ) . -Macros are not expanded inside quotes. -.Pp -For example: -.Bd -literal -offset indent -www1="10.0.0.1" -www2="10.0.0.2" -table webhosts { - check tcp - timeout 300 - real port 80 - host $www1 - host $www2 -} -.Ed -.Sh GLOBAL CONFIGURATION -Here are the settings that can be set globally: -.Pp -.Bl -tag -width Ds -compact -.It Xo -.Ic interval Ar number -.Xc -Set the interval in seconds at which the hosts will be checked. -The default interval is 10 seconds. -.Pp -.It Xo -.Ic timeout Ar number -.Xc -Set the global timeout in milliseconds for checks. -This can be overriden by the timeout value in the table definitions. -The default interval is 200 milliseconds and it must not exceed the -global interval. -.El -.Sh TABLES -Tables are used to group a set of hosts that can be checked using the same -method. -Only one health-checking method can be used per table. -Table specific configuration directives are described below. -.Bl -tag -width Ds -.It Ic check http Ar path Ic code Ar number -For each host in the table, verify that retrieving the URL -.Ar path -gives the HTTP return code -.Ar number . -.It Ic check http Ar path Ic digest Ar string -For each host in the table, verify that retrieving the URL -.Ar path -produces a content whose SHA1 digest is -.Ar digest . -The digest does not take the HTTP headers into account. -To compute the digest, use this simple command: -.Bd -literal -offset indent -ftp -o - http://host[:port]/path | sha1 -.Ed -.Pp -This gives a digest -that can be used as is in a digest statement: -.Bd -literal -offset indent -a9993e36476816aba3e25717850c26c9cd0d89d -.Ed -.It Ic check icmp -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 pattern -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 pattern -using shell globbing rules. -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 -Start the table disabled \(en no hosts will be checked in this table. -The table can be later enabled through -.Xr hostatectl 8 . -.It Ic host Ar address -Add the host whose address is -.Ar address -to the list of hosts to be checked in this table. -Each table needs at least one host. -.It Ic real port Ar port -When using the TCP or HTTP checking methods, use this -.Ar port -to connect to hosts. -This parameter is mandatory. -Main and backup tables need to have the same real port. -.It Ic timeout Ar number -Set the timeout in milliseconds for each host that is checked using -TCP as the transport. -This will override the global timeout, which is 200 milliseconds by default. -.El -.Sh SERVICES -Services represent a -.Xr pf 4 -rdr rule. -They are used to specify which addresses will be redirected -to the hosts in the specified tables. -The configuration directives that are valid in this context are described -below. -.Bl -tag -width Ds -.It Ic backup table Ar name -Specify the table to switch to when all hosts in the main table -are seen as down or disabled. -.It Ic disable -Set the service initially disabled. -It can be later enabled through -.Xr hostatectl 8 . -.It Ic sticky-address -This has the same effect than specifying sticky-address -for a rdr rule in -.Xr pf.conf 5 . -It will ensure that multiple connections from the same source are -mapped to the same redirection address. -.It Ic table Ar name -Specify the main table to be used. -This is mandatory. -.It Ic tag Ar name -Automatically tag packets passing through the -.Xr pf 4 -rdr rule with the name supplied. -This allows simpler filter rules. -.It Ic virtual ip Ar address Ic port Ar port -Specify an -.Ar address -and a -.Ar port -that will be used to redirect requests -to the hosts in the main or backup table. -Optionally an interface name can be given as follows, -to specify which interface the rdr rule will be enabled on: -.Bd -literal -offset indent -interface ``ifname'' -.Ed -.El -.Sh EXAMPLE -This configuration file would create a service -.Dq www -which load balances four hosts -and falls back to one host containing a -.Dq sorry page : -.Bd -literal -offset indent -www1=front-www1.private.example.com -www2=front-www2.private.example.com -www3=front-www3.private.example.com -www4=front-www4.private.example.com - -interval 5 - -table phphosts { - timeout 300 - real port 8080 - check http "/" digest 630aa3c2f... - host $www1 - host $www2 - host $www3 - host $www4 -} - -table sorryhost { - check icmp - disable - timeout 300 - real port 8080 - host sorryhost.private.example.com -} - -service www { - virtual ip www.example.com port 8080 interface trunk0 - virtual ip www6.example.com port 80 interface trunk0 - - tag HOSTATED - table phphosts - backup table sorryhost -} -.Ed -.Sh FILES -.Bl -tag -width "/etc/hostated.conf" -compact -.It Pa /etc/hostated.conf -.Xr hostated 8 -configuration file -.It Pa /etc/services -Service name database -.El -.Sh SEE ALSO -.Xr hostatectl 8 , -.Xr hostated 8 diff --git a/usr.sbin/hostated/hostated.h b/usr.sbin/hostated/hostated.h deleted file mode 100644 index ca592cbdad3..00000000000 --- a/usr.sbin/hostated/hostated.h +++ /dev/null @@ -1,354 +0,0 @@ -/* $OpenBSD: hostated.h,v 1.11 2007/01/08 20:46:18 reyk Exp $ */ - -/* - * Copyright (c) 2006 Pierre-Yves Ritschard <pyr@spootnik.org> - * Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.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. - */ - -#define CONF_FILE "/etc/hostated.conf" -#define HOSTATED_SOCKET "/var/run/hostated.sock" -#define PF_SOCKET "/dev/pf" -#define HOSTATED_USER "_hostated" -#define HOSTATED_ANCHOR "hostated" -#define CHECK_TIMEOUT 200 -#define CHECK_INTERVAL 10 -#define EMPTY_TABLE UINT_MAX -#define EMPTY_ID UINT_MAX -#define TABLE_NAME_SIZE 32 -#define TAG_NAME_SIZE 64 -#define SRV_NAME_SIZE 64 -#define MAX_NAME_SIZE 64 -#define SRV_MAX_VIRTS 16 - -#define SMALL_READ_BUF_SIZE 1024 -#define READ_BUF_SIZE 65535 - -/* buffer */ -struct buf { - TAILQ_ENTRY(buf) entry; - u_char *buf; - size_t size; - size_t max; - size_t wpos; - size_t rpos; -}; - -struct msgbuf { - TAILQ_HEAD(, buf) bufs; - u_int32_t queued; - int fd; -}; - -#define IMSG_HEADER_SIZE sizeof(struct imsg_hdr) -#define MAX_IMSGSIZE 8192 - -struct buf_read { - u_char buf[READ_BUF_SIZE]; - u_char *rptr; - size_t wpos; -}; - -struct imsgbuf { - TAILQ_HEAD(, imsg_fd) fds; - struct buf_read r; - struct msgbuf w; - struct event ev; - void (*handler)(int, short, void *); - int fd; - pid_t pid; - short events; -}; - -enum imsg_type { - IMSG_NONE, - IMSG_CTL_OK, /* answer to hostatectl requests */ - IMSG_CTL_FAIL, - IMSG_CTL_END, - IMSG_CTL_SERVICE, - IMSG_CTL_TABLE, - IMSG_CTL_HOST, - IMSG_CTL_SHOW_SUM, /* hostatectl requests */ - IMSG_CTL_SERVICE_ENABLE, - IMSG_CTL_SERVICE_DISABLE, - IMSG_CTL_TABLE_ENABLE, - IMSG_CTL_TABLE_DISABLE, - IMSG_CTL_HOST_ENABLE, - IMSG_CTL_HOST_DISABLE, - IMSG_CTL_SHUTDOWN, - IMSG_CTL_RELOAD, - IMSG_SERVICE_ENABLE, /* notifies from pfe to hce */ - IMSG_SERVICE_DISABLE, - IMSG_TABLE_ENABLE, - IMSG_TABLE_DISABLE, - IMSG_HOST_ENABLE, - IMSG_HOST_DISABLE, - IMSG_TABLE_STATUS, /* notifies from hce to pfe */ - IMSG_HOST_STATUS, - IMSG_SYNC -}; - -struct imsg_hdr { - enum imsg_type type; - u_int16_t len; - u_int32_t peerid; - pid_t pid; -}; - -struct imsg { - struct imsg_hdr hdr; - void *data; -}; - -typedef u_int32_t objid_t; - -struct ctl_status { - objid_t id; - int up; -}; - -struct ctl_id { - objid_t id; - char name[MAX_NAME_SIZE]; -}; - -struct ctl_icmp_event { - struct hostated *env; - int icmp_sock; - int icmp6_sock; - int has_icmp4; - int has_icmp6; - int last_up; - struct event ev; - struct timeval tv_start; -}; - -struct ctl_tcp_event { - int s; - struct buf *buf; - struct host *host; - struct table *table; - struct timeval tv_start; -}; - -struct address { - struct sockaddr_storage ss; - in_port_t port; - char ifname[IFNAMSIZ]; - TAILQ_ENTRY(address) entry; -}; -TAILQ_HEAD(addresslist, address); - -#define F_DISABLE 0x01 -#define F_BACKUP 0x02 -#define F_CHECK_DONE 0x02 /* reused for host */ -#define F_USED 0x04 -#define F_ACTIVE_RULESET 0x04 /* reused for service */ -#define F_DOWN 0x08 -#define F_ADD 0x10 -#define F_DEL 0x20 -#define F_CHANGED 0x40 -#define F_STICKY 0x80 - -struct host { - u_int8_t flags; - objid_t id; - objid_t tableid; - char *tablename; - char name[MAXHOSTNAMELEN]; - int up; - int last_up; - struct sockaddr_storage ss; - struct ctl_tcp_event cte; - TAILQ_ENTRY(host) entry; -}; -TAILQ_HEAD(hostlist, host); - -#define HOST_DOWN -1 -#define HOST_UNKNOWN 0 -#define HOST_UP 1 - -struct table { - objid_t id; - objid_t serviceid; - u_int8_t flags; - int check; - int up; - in_port_t port; - int retcode; - 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; - TAILQ_ENTRY(table) entry; -}; -TAILQ_HEAD(tablelist, table); - -#define CHECK_NOCHECK 0 -#define CHECK_ICMP 1 -#define CHECK_TCP 2 -#define CHECK_HTTP_CODE 3 -#define CHECK_HTTP_DIGEST 4 -#define CHECK_SEND_EXPECT 5 - -struct service { - objid_t id; - u_int8_t flags; - in_port_t port; - char name[SRV_NAME_SIZE]; - char tag[TAG_NAME_SIZE]; - struct addresslist virts; - struct table *table; - struct table *backup; /* use this if no host up */ - TAILQ_ENTRY(service) entry; -}; -TAILQ_HEAD(servicelist, service); - -enum { - PROC_MAIN, - PROC_PFE, - PROC_HCE -} hostated_process; - -struct hostated { - u_int8_t opts; - struct pfdata *pf; - int icmp_sock; - int icmp6_sock; - int tablecount; - int servicecount; - struct timeval interval; - struct timeval timeout; - struct table empty_table; - struct event ev; - struct tablelist tables; - struct servicelist services; - struct ctl_icmp_event cie; -}; - -#define HOSTATED_OPT_VERBOSE 0x01 -#define HOSTATED_OPT_NOACTION 0x04 - -/* initially control.h */ -struct { - struct event ev; - int fd; -} control_state; - -enum blockmodes { - BM_NORMAL, - BM_NONBLOCK -}; - -struct ctl_conn { - TAILQ_ENTRY(ctl_conn) entry; - struct imsgbuf ibuf; - -}; -TAILQ_HEAD(ctl_connlist, ctl_conn); - -/* control.c */ -int control_init(void); -int control_listen(void); -void control_accept(int, short, void *); -void control_dispatch_imsg(int, short, void *); -int control_imsg_relay(struct imsg *); -void control_cleanup(void); - -void session_socket_blockmode(int, enum blockmodes); - -extern struct ctl_connlist ctl_conns; - -/* parse.y */ -int parse_config(struct hostated *, const char *, int); - -/* log.c */ -void log_init(int); -void log_warn(const char *, ...); -void log_warnx(const char *, ...); -void log_info(const char *, ...); -void log_debug(const char *, ...); -void fatal(const char *); -void fatalx(const char *); - -/* buffer.c */ -struct buf *buf_open(size_t); -struct buf *buf_dynamic(size_t, size_t); -int buf_add(struct buf *, void *, size_t); -void *buf_reserve(struct buf *, size_t); -void *buf_seek(struct buf *, size_t, size_t); -int buf_close(struct msgbuf *, struct buf *); -void buf_free(struct buf *); -void msgbuf_init(struct msgbuf *); -void msgbuf_clear(struct msgbuf *); -int msgbuf_write(struct msgbuf *); - -/* imsg.c */ -void imsg_init(struct imsgbuf *, int, void (*)(int, short, void *)); -ssize_t imsg_read(struct imsgbuf *); -ssize_t imsg_get(struct imsgbuf *, struct imsg *); -int imsg_compose(struct imsgbuf *, enum imsg_type, u_int32_t, pid_t, - void *, u_int16_t); -struct buf *imsg_create(struct imsgbuf *, enum imsg_type, u_int32_t, pid_t, - u_int16_t); -int imsg_add(struct buf *, void *, u_int16_t); -int imsg_close(struct imsgbuf *, struct buf *); -void imsg_free(struct imsg *); -void imsg_event_add(struct imsgbuf *); /* needs to be provided externally */ - -/* pfe.c */ -pid_t pfe(struct hostated *, int [2], int [2], int [2]); -void show(struct ctl_conn *); -int enable_service(struct ctl_conn *, struct ctl_id *); -int enable_table(struct ctl_conn *, struct ctl_id *); -int enable_host(struct ctl_conn *, struct ctl_id *); -int disable_service(struct ctl_conn *, struct ctl_id *); -int disable_table(struct ctl_conn *, struct ctl_id *); -int disable_host(struct ctl_conn *, struct ctl_id *); - -/* pfe_filter.c */ -void init_filter(struct hostated *); -void init_tables(struct hostated *); -void flush_table(struct hostated *, struct service *); -void sync_table(struct hostated *, struct service *, struct table *); -void sync_ruleset(struct hostated *, struct service *, int); -void flush_rulesets(struct hostated *); - -/* hce.c */ -pid_t hce(struct hostated *, int [2], int [2], int [2]); -void hce_notify_done(struct host *, const char *); - -/* check_icmp.c */ -void schedule_icmp(struct ctl_icmp_event *, struct table *); -void check_icmp(struct ctl_icmp_event *); - -/* check_tcp.c */ -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); -struct service *service_find(struct hostated *, objid_t); -struct host *host_findbyname(struct hostated *, const char *); -struct table *table_findbyname(struct hostated *, const char *); -struct service *service_findbyname(struct hostated *, const char *); diff --git a/usr.sbin/hostated/imsg.c b/usr.sbin/hostated/imsg.c deleted file mode 100644 index 37c1808e293..00000000000 --- a/usr.sbin/hostated/imsg.c +++ /dev/null @@ -1,181 +0,0 @@ -/* $OpenBSD: imsg.c,v 1.3 2007/01/08 20:46:18 reyk Exp $ */ - -/* - * Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.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/socket.h> -#include <sys/queue.h> -#include <sys/uio.h> -#include <sys/param.h> -#include <net/if.h> -#include <errno.h> -#include <event.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> - -#include "hostated.h" - -void -imsg_init(struct imsgbuf *ibuf, int fd, void (*handler)(int, short, void *)) -{ - msgbuf_init(&ibuf->w); - bzero(&ibuf->r, sizeof(ibuf->r)); - ibuf->fd = fd; - ibuf->w.fd = fd; - ibuf->pid = getpid(); - ibuf->handler = handler; - TAILQ_INIT(&ibuf->fds); -} - -ssize_t -imsg_read(struct imsgbuf *ibuf) -{ - ssize_t n; - - if ((n = recv(ibuf->fd, ibuf->r.buf + ibuf->r.wpos, - sizeof(ibuf->r.buf) - ibuf->r.wpos, 0)) == -1) { - if (errno != EINTR && errno != EAGAIN) { - log_warn("imsg_read: pipe read error"); - return (-1); - } - return (0); - } - - ibuf->r.wpos += n; - - return (n); -} - -ssize_t -imsg_get(struct imsgbuf *ibuf, struct imsg *imsg) -{ - size_t av, left, datalen; - - av = ibuf->r.wpos; - - if (IMSG_HEADER_SIZE > av) - return (0); - - memcpy(&imsg->hdr, ibuf->r.buf, sizeof(imsg->hdr)); - if (imsg->hdr.len < IMSG_HEADER_SIZE || - imsg->hdr.len > MAX_IMSGSIZE) { - log_warnx("imsg_get: imsg hdr len %u out of bounds, type=%u", - imsg->hdr.len, imsg->hdr.type); - return (-1); - } - if (imsg->hdr.len > av) - return (0); - datalen = imsg->hdr.len - IMSG_HEADER_SIZE; - ibuf->r.rptr = ibuf->r.buf + IMSG_HEADER_SIZE; - if ((imsg->data = malloc(datalen)) == NULL) { - log_warn("imsg_get"); - return (-1); - } - memcpy(imsg->data, ibuf->r.rptr, datalen); - - if (imsg->hdr.len < av) { - left = av - imsg->hdr.len; - memmove(&ibuf->r.buf, ibuf->r.buf + imsg->hdr.len, left); - ibuf->r.wpos = left; - } else - ibuf->r.wpos = 0; - - return (datalen + IMSG_HEADER_SIZE); -} - -int -imsg_compose(struct imsgbuf *ibuf, enum imsg_type type, u_int32_t peerid, - pid_t pid, void *data, u_int16_t datalen) -{ - struct buf *wbuf; - int n; - - if ((wbuf = imsg_create(ibuf, type, peerid, pid, datalen)) == NULL) - return (-1); - - if (imsg_add(wbuf, data, datalen) == -1) - return (-1); - - if ((n = imsg_close(ibuf, wbuf)) < 0) - return (-1); - - return (n); -} - -/* ARGSUSED */ -struct buf * -imsg_create(struct imsgbuf *ibuf, enum imsg_type type, u_int32_t peerid, - pid_t pid, u_int16_t datalen) -{ - struct buf *wbuf; - struct imsg_hdr hdr; - - if (datalen > MAX_IMSGSIZE - IMSG_HEADER_SIZE) { - log_warnx("imsg_create: len %u > MAX_IMSGSIZE; " - "type %u peerid %lu", datalen + IMSG_HEADER_SIZE, - type, peerid); - return (NULL); - } - - hdr.len = (u_int16_t)(datalen + IMSG_HEADER_SIZE); - hdr.type = type; - hdr.peerid = peerid; - if ((hdr.pid = pid) == 0) - hdr.pid = ibuf->pid; - if ((wbuf = buf_open(hdr.len)) == NULL) { - log_warn("imsg_create: buf_open"); - return (NULL); - } - if (imsg_add(wbuf, &hdr, sizeof(hdr)) == -1) - return (NULL); - - return (wbuf); -} - -int -imsg_add(struct buf *msg, void *data, u_int16_t datalen) -{ - if (datalen) - if (buf_add(msg, data, datalen) == -1) { - log_warnx("imsg_add: buf_add error"); - buf_free(msg); - return (-1); - } - return (datalen); -} - -int -imsg_close(struct imsgbuf *ibuf, struct buf *msg) -{ - int n; - - if ((n = buf_close(&ibuf->w, msg)) < 0) { - log_warnx("imsg_close: buf_close error"); - buf_free(msg); - return (-1); - } - imsg_event_add(ibuf); - - return (n); -} - -void -imsg_free(struct imsg *imsg) -{ - free(imsg->data); -} diff --git a/usr.sbin/hostated/log.c b/usr.sbin/hostated/log.c deleted file mode 100644 index 990f0fcde62..00000000000 --- a/usr.sbin/hostated/log.c +++ /dev/null @@ -1,159 +0,0 @@ -/* $OpenBSD: log.c,v 1.2 2006/12/16 17:48:27 deraadt Exp $ */ - -/* - * Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.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 MIND, 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 <errno.h> -#include <stdarg.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <syslog.h> - -/* prototypes */ -void log_init(int); -void vlog(int, const char *, va_list); -void log_warn(const char *, ...); -void log_warnx(const char *, ...); -void log_info(const char *, ...); -void log_debug(const char *, ...); -void fatal(const char *); -void fatalx(const char *); - -int debug; - -void logit(int, const char *, ...); - -void -log_init(int n_debug) -{ - extern char *__progname; - - debug = n_debug; - - if (!debug) - openlog(__progname, LOG_PID | LOG_NDELAY, LOG_DAEMON); - - tzset(); -} - -void -logit(int pri, const char *fmt, ...) -{ - va_list ap; - - va_start(ap, fmt); - vlog(pri, fmt, ap); - va_end(ap); -} - -void -vlog(int pri, const char *fmt, va_list ap) -{ - char *nfmt; - - if (debug) { - /* best effort in out of mem situations */ - if (asprintf(&nfmt, "%s\n", fmt) == -1) { - vfprintf(stderr, fmt, ap); - fprintf(stderr, "\n"); - } else { - vfprintf(stderr, nfmt, ap); - free(nfmt); - } - fflush(stderr); - } else - vsyslog(pri, fmt, ap); -} - - -void -log_warn(const char *emsg, ...) -{ - char *nfmt; - va_list ap; - - /* best effort to even work in out of memory situations */ - if (emsg == NULL) - logit(LOG_CRIT, "%s", strerror(errno)); - else { - va_start(ap, emsg); - - if (asprintf(&nfmt, "%s: %s", emsg, strerror(errno)) == -1) { - /* we tried it... */ - vlog(LOG_CRIT, emsg, ap); - logit(LOG_CRIT, "%s", strerror(errno)); - } else { - vlog(LOG_CRIT, nfmt, ap); - free(nfmt); - } - va_end(ap); - } -} - -void -log_warnx(const char *emsg, ...) -{ - va_list ap; - - va_start(ap, emsg); - vlog(LOG_CRIT, emsg, ap); - va_end(ap); -} - -void -log_info(const char *emsg, ...) -{ - va_list ap; - - va_start(ap, emsg); - vlog(LOG_INFO, emsg, ap); - va_end(ap); -} - -void -log_debug(const char *emsg, ...) -{ - va_list ap; - - if (debug) { - va_start(ap, emsg); - vlog(LOG_DEBUG, emsg, ap); - va_end(ap); - } -} - -void -fatal(const char *emsg) -{ - if (emsg == NULL) - logit(LOG_CRIT, "fatal: %s", strerror(errno)); - else - if (errno) - logit(LOG_CRIT, "fatal: %s: %s", - emsg, strerror(errno)); - else - logit(LOG_CRIT, "fatal: %s", emsg); - - exit(1); -} - -void -fatalx(const char *emsg) -{ - errno = 0; - fatal(emsg); -} diff --git a/usr.sbin/hostated/parse.y b/usr.sbin/hostated/parse.y deleted file mode 100644 index 38af6b6808a..00000000000 --- a/usr.sbin/hostated/parse.y +++ /dev/null @@ -1,1023 +0,0 @@ -/* $OpenBSD: parse.y,v 1.13 2007/01/08 20:46:18 reyk Exp $ */ - -/* - * Copyright (c) 2006 Pierre-Yves Ritschard <pyr@spootnik.org> - * Copyright (c) 2004, 2005 Esben Norby <norby@openbsd.org> - * Copyright (c) 2004 Ryan McBride <mcbride@openbsd.org> - * Copyright (c) 2002, 2003, 2004 Henning Brauer <henning@openbsd.org> - * Copyright (c) 2001 Markus Friedl. All rights reserved. - * Copyright (c) 2001 Daniel Hartmeier. All rights reserved. - * Copyright (c) 2001 Theo de Raadt. All rights reserved. - * - * 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/socket.h> -#include <sys/queue.h> -#include <netinet/in.h> -#include <net/if.h> -#include <arpa/inet.h> -#include <arpa/nameser.h> - -#include <ctype.h> -#include <err.h> -#include <errno.h> -#include <event.h> -#include <limits.h> -#include <stdarg.h> -#include <stdio.h> -#include <netdb.h> -#include <string.h> - -#include "hostated.h" - -struct hostated *conf = NULL; -static FILE *fin = NULL; -static int lineno = 1; -static int errors = 0; -const char *infile; -char *start_state; -objid_t last_service_id = 0; -objid_t last_table_id = 0; -objid_t last_host_id = 0; - -static struct service *service = NULL; -static struct table *table = NULL; - -int yyerror(const char *, ...); -int yyparse(void); -int kw_cmp(const void *, const void *); -int lookup(char *); -int lgetc(FILE *); -int lungetc(int); -int findeol(void); -int yylex(void); - -TAILQ_HEAD(symhead, sym) symhead = TAILQ_HEAD_INITIALIZER(symhead); -struct sym { - TAILQ_ENTRY(sym) entries; - int used; - int persist; - char *nam; - char *val; -}; - -int symset(const char *, const char *, int); -char *symget(const char *); -int cmdline_symset(char *); - -struct address *host_v4(const char *); -struct address *host_v6(const char *); -int host_dns(const char *, struct addresslist *, - int, in_port_t, const char *); -int host(const char *, struct addresslist *, - int, in_port_t, const char *); - -typedef struct { - union { - u_int32_t number; - char *string; - struct host *host; - struct timeval tv; - } v; - int lineno; -} YYSTYPE; - -%} - -%token SERVICE TABLE BACKUP HOST REAL -%token CHECK HTTP 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 -%type <v.number> number port -%type <v.host> host -%type <v.tv> timeout - -%% - -grammar : /* empty */ - | grammar '\n' - | grammar varset '\n' - | grammar main '\n' - | grammar service '\n' - | grammar table '\n' - | grammar error '\n' { errors++; } - ; - -number : STRING { - const char *estr; - - $$ = strtonum($1, 0, UINT_MAX, &estr); - if (estr) { - yyerror("cannot parse number %s : %s", - $1, estr); - free($1); - YYERROR; - } - free($1); - } - ; - -port : PORT STRING { - const char *estr; - struct servent *servent; - - $$ = strtonum($2, 1, USHRT_MAX, &estr); - if (estr) { - if (errno == ERANGE) { - yyerror("port %s is out of range", $2); - free($2); - YYERROR; - } - servent = getservbyname($2, "tcp"); - if (servent == NULL) { - yyerror("port %s is invalid", $2); - free($2); - YYERROR; - } - $$ = servent->s_port; - } else - $$ = htons($$); - free($2); - } - | PORT HTTP { - struct servent *servent; - - servent = getservbyname("http", "tcp"); - if (servent == NULL) - $$ = htons(80); - else - $$ = servent->s_port; - } - ; - -varset : STRING '=' STRING { - if (symset($1, $3, 0) == -1) - fatal("cannot store variable"); - free($1); - free($3); - } - ; - -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.tv_sec = $2; } - | TIMEOUT timeout { - bcopy(&$2, &conf->timeout, sizeof(struct timeval)); - } - ; - -service : SERVICE STRING { - struct service *srv; - - TAILQ_FOREACH(srv, &conf->services, entry) - if (!strcmp(srv->name, $2)) - break; - if (srv != NULL) { - yyerror("service %s defined twice", $2); - free($2); - YYERROR; - } - if ((srv = calloc(1, sizeof (*srv))) == NULL) - fatal("out of memory"); - - if (strlcpy(srv->name, $2, sizeof(srv->name)) >= - sizeof(srv->name)) { - yyerror("service name truncated"); - YYERROR; - } - free($2); - srv->id = last_service_id++; - if (last_service_id == UINT_MAX) { - yyerror("too many services defined"); - YYERROR; - } - service = srv; - } '{' optnl serviceopts_l '}' { - if (service->table == NULL) { - yyerror("service %s has no table", - service->name); - YYERROR; - } - if (TAILQ_EMPTY(&service->virts)) { - yyerror("service %s has no virtual ip", - service->name); - YYERROR; - } - conf->servicecount++; - if (service->backup == NULL) - service->backup = &conf->empty_table; - else if (service->backup->port != - service->table->port) { - yyerror("service %s uses two different ports " - "for its table and backup table", - service->name); - YYERROR; - } - - if (!(service->flags & F_DISABLE)) - service->flags |= F_ADD; - TAILQ_INSERT_HEAD(&conf->services, service, entry); - } - ; - -serviceopts_l : serviceopts_l serviceoptsl nl - | serviceoptsl optnl - ; - -serviceoptsl : TABLE STRING { - struct table *tb; - - TAILQ_FOREACH(tb, &conf->tables, entry) - if (!strcmp(tb->name, $2)) - break; - if (tb == NULL) { - yyerror("no such table: %s", $2); - free($2); - YYERROR; - } else { - service->table = tb; - service->table->serviceid = service->id; - service->table->flags |= F_USED; - free($2); - } - } - | BACKUP TABLE STRING { - struct table *tb; - - if (service->backup) { - yyerror("backup already specified"); - free($3); - YYERROR; - } - - TAILQ_FOREACH(tb, &conf->tables, entry) - if (!strcmp(tb->name, $3)) - break; - - if (tb == NULL) { - yyerror("no such table: %s", $3); - free($3); - YYERROR; - } else { - service->backup = tb; - service->backup->serviceid = service->id; - service->backup->flags |= (F_USED|F_BACKUP); - free($3); - } - } - | VIRTUAL IP STRING port interface { - if (host($3, &service->virts, - SRV_MAX_VIRTS, $4, $5) <= 0) { - yyerror("invalid virtual ip: %s", $3); - free($3); - free($5); - YYERROR; - } - free($3); - free($5); - } - | DISABLE { service->flags |= F_DISABLE; } - | STICKYADDR { service->flags |= F_STICKY; } - | TAG STRING { - if (strlcpy(service->tag, $2, sizeof(service->tag)) >= - sizeof(service->tag)) { - yyerror("service tag name truncated"); - free($2); - YYERROR; - } - free($2); - } - ; - -table : TABLE STRING { - struct table *tb; - - TAILQ_FOREACH(tb, &conf->tables, entry) - if (!strcmp(tb->name, $2)) - break; - if (tb != NULL) { - yyerror("table %s defined twice"); - free($2); - YYERROR; - } - - if ((tb = calloc(1, sizeof (*tb))) == NULL) - fatal("out of memory"); - - if (strlcpy(tb->name, $2, sizeof(tb->name)) >= - sizeof(tb->name)) { - yyerror("table name truncated"); - YYERROR; - } - tb->id = last_table_id++; - bcopy(&conf->timeout, &tb->timeout, - sizeof(struct timeval)); - if (last_table_id == UINT_MAX) { - yyerror("too many tables defined"); - YYERROR; - } - free($2); - table = tb; - } '{' optnl tableopts_l '}' { - if (table->port == 0) { - yyerror("table %s has no port", table->name); - YYERROR; - } - if (TAILQ_EMPTY(&table->hosts)) { - yyerror("table %s has no hosts", table->name); - YYERROR; - } - if (table->check == CHECK_NOCHECK) { - yyerror("table %s has no check", table->name); - YYERROR; - } - conf->tablecount++; - TAILQ_INSERT_HEAD(&conf->tables, table, entry); - } - ; - -tableopts_l : tableopts_l tableoptsl nl - | tableoptsl optnl - ; - -tableoptsl : host { - $1->tableid = table->id; - $1->tablename = table->name; - TAILQ_INSERT_HEAD(&table->hosts, $1, entry); - } - | TIMEOUT timeout { - bcopy(&$2, &table->timeout, sizeof(struct timeval)); - } - | CHECK ICMP { - table->check = CHECK_ICMP; - } - | CHECK TCP { - table->check = CHECK_TCP; - } - | CHECK HTTP STRING CODE number { - table->check = CHECK_HTTP_CODE; - table->retcode = $5; - if (strlcpy(table->path, $3, sizeof(table->path)) >= - sizeof(table->path)) { - yyerror("http path truncated"); - free($3); - YYERROR; - } - } - | CHECK HTTP STRING DIGEST STRING { - table->check = CHECK_HTTP_DIGEST; - if (strlcpy(table->path, $3, sizeof(table->path)) >= - sizeof(table->path)) { - yyerror("http path truncated"); - free($3); - free($5); - YYERROR; - } - if (strlcpy(table->digest, $5, - sizeof(table->digest)) >= sizeof(table->digest)) { - yyerror("http digest truncated"); - free($3); - free($5); - YYERROR; - } - free($3); - free($5); - } - | CHECK SEND sendbuf EXPECT STRING { - table->check = CHECK_SEND_EXPECT; - if (strlcpy(table->exbuf, $5, sizeof(table->exbuf)) - >= sizeof(table->exbuf)) { - yyerror("yyparse: expect buffer truncated"); - free($5); - YYERROR; - } - free($5); - } - | REAL port { - table->port = $2; - } - | DISABLE { table->flags |= F_DISABLE; } - ; - -interface : /*empty*/ { $$ = NULL; } - | INTERFACE STRING { $$ = $2; } - ; - -host : HOST STRING { - struct host *r; - struct address *a; - struct addresslist al; - - if ((r = calloc(1, sizeof(*r))) == NULL) - fatal("out of memory"); - - TAILQ_INIT(&al); - if (host($2, &al, 1, 0, NULL) <= 0) { - yyerror("invalid host %s", $2); - free($2); - YYERROR; - } - a = TAILQ_FIRST(&al); - memcpy(&r->ss, &a->ss, sizeof(r->ss)); - free(a); - - if (strlcpy(r->name, $2, sizeof(r->name)) >= - sizeof(r->name)) { - yyerror("host name truncated"); - free($2); - YYERROR; - } else { - r->id = last_host_id++; - if (last_host_id == UINT_MAX) { - yyerror("too many hosts defined"); - YYERROR; - } - free($2); - $$ = r; - } - } - ; - -timeout : number - { - $$.tv_sec = $1 / 1000; - $$.tv_usec = ($1 % 1000) * 1000; - } - ; - -optnl : '\n' optnl - | - ; - -nl : '\n' optnl - ; - -%% - -struct keywords { - const char *k_name; - int k_val; -}; - -int -yyerror(const char *fmt, ...) -{ - va_list ap; - - errors = 1; - va_start(ap, fmt); - fprintf(stderr, "%s:%d: ", infile, yylval.lineno); - vfprintf(stderr, fmt, ap); - fprintf(stderr, "\n"); - va_end(ap); - return (0); -} - -int -kw_cmp(const void *k, const void *e) -{ - - return (strcmp(k, ((const struct keywords *)e)->k_name)); -} - -int -lookup(char *s) -{ - /* this has to be sorted always */ - static const struct keywords keywords[] = { - { "backup", BACKUP }, - { "check", CHECK }, - { "code", CODE }, - { "digest", DIGEST }, - { "disable", DISABLE }, - { "expect", EXPECT }, - { "external", EXTERNAL }, - { "host", HOST }, - { "http", HTTP }, - { "icmp", ICMP }, - { "interface", INTERFACE }, - { "interval", INTERVAL }, - { "ip", IP }, - { "nothing", NOTHING }, - { "port", PORT }, - { "real", REAL }, - { "send", SEND }, - { "service", SERVICE }, - { "sticky-address", STICKYADDR }, - { "table", TABLE }, - { "tag", TAG }, - { "tcp", TCP }, - { "timeout", TIMEOUT }, - { "virtual", VIRTUAL } - }; - const struct keywords *p; - - p = bsearch(s, keywords, sizeof(keywords)/sizeof(keywords[0]), - sizeof(keywords[0]), kw_cmp); - - if (p) - return (p->k_val); - else - return (STRING); -} - -#define MAXPUSHBACK 128 - -char *parsebuf; -int parseindex; -char pushback_buffer[MAXPUSHBACK]; -int pushback_index = 0; - -int -lgetc(FILE *f) -{ - int c, next; - - if (parsebuf) { - /* Read character from the parsebuffer instead of input. */ - if (parseindex >= 0) { - c = parsebuf[parseindex++]; - if (c != '\0') - return (c); - parsebuf = NULL; - } else - parseindex++; - } - - if (pushback_index) - return (pushback_buffer[--pushback_index]); - - while ((c = getc(f)) == '\\') { - next = getc(f); - if (next == 'n') { - c = '\n'; - break; - } else if (next == 'r') { - c = '\r'; - break; - } else if (next != '\n') { - c = next; - break; - } - yylval.lineno = lineno; - lineno++; - } - if (c == '\t' || c == ' ') { - /* Compress blanks to a single space. */ - do { - c = getc(f); - } while (c == '\t' || c == ' '); - ungetc(c, f); - c = ' '; - } - - return (c); -} - -int -lungetc(int c) -{ - if (c == EOF) - return (EOF); - if (parsebuf) { - parseindex--; - if (parseindex >= 0) - return (c); - } - if (pushback_index < MAXPUSHBACK-1) - return (pushback_buffer[pushback_index++] = c); - else - return (EOF); -} - -int -findeol(void) -{ - int c; - - parsebuf = NULL; - pushback_index = 0; - - /* skip to either EOF or the first real EOL */ - while (1) { - c = lgetc(fin); - if (c == '\n') { - lineno++; - break; - } - if (c == EOF) - break; - } - return (ERROR); -} - -int -yylex(void) -{ - char buf[8096]; - char *p, *val; - int endc, c; - int token; - -top: - p = buf; - while ((c = lgetc(fin)) == ' ') - ; /* nothing */ - - yylval.lineno = lineno; - if (c == '#') - while ((c = lgetc(fin)) != '\n' && c != EOF) - ; /* nothing */ - if (c == '$' && parsebuf == NULL) { - while (1) { - if ((c = lgetc(fin)) == EOF) - return (0); - - if (p + 1 >= buf + sizeof(buf) - 1) { - yyerror("string too long"); - return (findeol()); - } - if (isalnum(c) || c == '_') { - *p++ = (char)c; - continue; - } - *p = '\0'; - lungetc(c); - break; - } - val = symget(buf); - if (val == NULL) { - yyerror("macro '%s' not defined", buf); - return (findeol()); - } - parsebuf = val; - parseindex = 0; - goto top; - } - - switch (c) { - case '\'': - case '"': - endc = c; - while (1) { - if ((c = lgetc(fin)) == EOF) - return (0); - if (c == endc) { - *p = '\0'; - break; - } - if (c == '\n') { - lineno++; - continue; - } - if (p + 1 >= buf + sizeof(buf) - 1) { - yyerror("string too long"); - return (findeol()); - } - *p++ = (char)c; - } - yylval.v.string = strdup(buf); - if (yylval.v.string == NULL) - errx(1, "yylex: strdup"); - return (STRING); - } - -#define allowed_in_string(x) \ - (isalnum(x) || (ispunct(x) && x != '(' && x != ')' && \ - x != '{' && x != '}' && \ - x != '!' && x != '=' && x != '#' && \ - x != ',')) - - if (isalnum(c) || c == ':' || c == '_') { - do { - *p++ = c; - if ((unsigned)(p-buf) >= sizeof(buf)) { - yyerror("string too long"); - return (findeol()); - } - } while ((c = lgetc(fin)) != EOF && (allowed_in_string(c))); - lungetc(c); - *p = '\0'; - if ((token = lookup(buf)) == STRING) - if ((yylval.v.string = strdup(buf)) == NULL) - err(1, "yylex: strdup"); - return (token); - } - if (c == '\n') { - yylval.lineno = lineno; - lineno++; - } - if (c == EOF) - return (0); - return (c); -} - -int -parse_config(struct hostated *x_conf, const char *filename, int opts) -{ - struct sym *sym, *next; - - conf = x_conf; - - TAILQ_INIT(&conf->services); - TAILQ_INIT(&conf->tables); - memset(&conf->empty_table, 0, sizeof(conf->empty_table)); - conf->empty_table.id = EMPTY_TABLE; - conf->empty_table.flags |= F_DISABLE; - (void)strlcpy(conf->empty_table.name, "empty", - sizeof(conf->empty_table.name)); - - conf->timeout.tv_sec = CHECK_TIMEOUT / 1000; - conf->timeout.tv_usec = (CHECK_TIMEOUT % 1000) * 1000; - conf->interval.tv_sec = CHECK_INTERVAL; - conf->interval.tv_usec = 0; - conf->opts = opts; - - if ((fin = fopen(filename, "r")) == NULL) { - warn("%s", filename); - return (NULL); - } - infile = filename; - setservent(1); - yyparse(); - endservent(); - fclose(fin); - - /* Free macros and check which have not been used. */ - for (sym = TAILQ_FIRST(&symhead); sym != NULL; sym = next) { - next = TAILQ_NEXT(sym, entries); - if ((conf->opts & HOSTATED_OPT_VERBOSE) && !sym->used) - fprintf(stderr, "warning: macro '%s' not " - "used\n", sym->nam); - if (!sym->persist) { - free(sym->nam); - free(sym->val); - TAILQ_REMOVE(&symhead, sym, entries); - free(sym); - } - } - - if (TAILQ_EMPTY(&conf->services)) { - log_warnx("no services, nothing to do"); - errors++; - } - - if (timercmp(&conf->timeout, &conf->interval, >=)) { - log_warnx("global timeout exceeds interval"); - errors++; - } - - /* Verify that every table is used */ - TAILQ_FOREACH(table, &conf->tables, entry) { - if (!(table->flags & F_USED)) { - log_warnx("unused table: %s", table->name); - errors++; - } - if (timercmp(&table->timeout, &conf->interval, >=)) { - log_warnx("table timeout exceeds interval: %s", - table->name); - errors++; - } - } - - if (errors) { - bzero(&conf, sizeof (*conf)); - return (-1); - } - - return (0); -} - -int -symset(const char *nam, const char *val, int persist) -{ - struct sym *sym; - - for (sym = TAILQ_FIRST(&symhead); sym && strcmp(nam, sym->nam); - sym = TAILQ_NEXT(sym, entries)) - ; /* nothing */ - - if (sym != NULL) { - if (sym->persist == 1) - return (0); - else { - free(sym->nam); - free(sym->val); - TAILQ_REMOVE(&symhead, sym, entries); - free(sym); - } - } - if ((sym = calloc(1, sizeof(*sym))) == NULL) - return (-1); - - sym->nam = strdup(nam); - if (sym->nam == NULL) { - free(sym); - return (-1); - } - sym->val = strdup(val); - if (sym->val == NULL) { - free(sym->nam); - free(sym); - return (-1); - } - sym->used = 0; - sym->persist = persist; - TAILQ_INSERT_TAIL(&symhead, sym, entries); - return (0); -} - -int -cmdline_symset(char *s) -{ - char *sym, *val; - int ret; - size_t len; - - if ((val = strrchr(s, '=')) == NULL) - return (-1); - - len = strlen(s) - strlen(val) + 1; - if ((sym = malloc(len)) == NULL) - errx(1, "cmdline_symset: malloc"); - - strlcpy(sym, s, len); - - ret = symset(sym, val + 1, 1); - free(sym); - - return (ret); -} - -char * -symget(const char *nam) -{ - struct sym *sym; - - TAILQ_FOREACH(sym, &symhead, entries) - if (strcmp(nam, sym->nam) == 0) { - sym->used = 1; - return (sym->val); - } - return (NULL); -} - -struct address * -host_v4(const char *s) -{ - struct in_addr ina; - struct sockaddr_in *sain; - struct address *h; - - bzero(&ina, sizeof(ina)); - if (inet_pton(AF_INET, s, &ina) != 1) - return (NULL); - - if ((h = calloc(1, sizeof(*h))) == NULL) - fatal(NULL); - sain = (struct sockaddr_in *)&h->ss; - sain->sin_len = sizeof(struct sockaddr_in); - sain->sin_family = AF_INET; - sain->sin_addr.s_addr = ina.s_addr; - - return (h); -} - -struct address * -host_v6(const char *s) -{ - struct in6_addr ina6; - struct sockaddr_in6 *sin6; - struct address *h; - - bzero(&ina6, sizeof(ina6)); - if (inet_pton(AF_INET6, s, &ina6) != 1) - return (NULL); - - if ((h = calloc(1, sizeof(*h))) == NULL) - fatal(NULL); - sin6 = (struct sockaddr_in6 *)&h->ss; - sin6->sin6_len = sizeof(struct sockaddr_in6); - sin6->sin6_family = AF_INET6; - memcpy(&sin6->sin6_addr, &ina6, sizeof(ina6)); - - return (h); -} - -int -host_dns(const char *s, struct addresslist *al, int max, - in_port_t port, const char *ifname) -{ - struct addrinfo hints, *res0, *res; - int error, cnt = 0; - struct sockaddr_in *sain; - struct sockaddr_in6 *sin6; - struct address *h; - - bzero(&hints, sizeof(hints)); - hints.ai_family = PF_UNSPEC; - hints.ai_socktype = SOCK_DGRAM; /* DUMMY */ - error = getaddrinfo(s, NULL, &hints, &res0); - if (error == EAI_AGAIN || error == EAI_NODATA || error == EAI_NONAME) - return (0); - if (error) { - log_warnx("host_dns: could not parse \"%s\": %s", s, - gai_strerror(error)); - return (-1); - } - - for (res = res0; res && cnt < max; res = res->ai_next) { - if (res->ai_family != AF_INET && - res->ai_family != AF_INET6) - continue; - if ((h = calloc(1, sizeof(*h))) == NULL) - fatal(NULL); - - h->port = port; - if (ifname != NULL) { - if (strlcpy(h->ifname, ifname, sizeof(h->ifname)) >= - sizeof(h->ifname)) - log_warnx("host_dns: interface name truncated"); - return (-1); - } - h->ss.ss_family = res->ai_family; - if (res->ai_family == AF_INET) { - sain = (struct sockaddr_in *)&h->ss; - sain->sin_len = sizeof(struct sockaddr_in); - sain->sin_addr.s_addr = ((struct sockaddr_in *) - res->ai_addr)->sin_addr.s_addr; - } else { - sin6 = (struct sockaddr_in6 *)&h->ss; - sin6->sin6_len = sizeof(struct sockaddr_in6); - memcpy(&sin6->sin6_addr, &((struct sockaddr_in6 *) - res->ai_addr)->sin6_addr, sizeof(struct in6_addr)); - } - - TAILQ_INSERT_HEAD(al, h, entry); - cnt++; - } - if (cnt == max && res) { - log_warnx("host_dns: %s resolves to more than %d hosts", - s, max); - } - freeaddrinfo(res0); - return (cnt); -} - -int -host(const char *s, struct addresslist *al, int max, - in_port_t port, const char *ifname) -{ - struct address *h; - - h = host_v4(s); - - /* IPv6 address? */ - if (h == NULL) - h = host_v6(s); - - if (h != NULL) { - h->port = port; - if (ifname != NULL) { - if (strlcpy(h->ifname, ifname, sizeof(h->ifname)) >= - sizeof(h->ifname)) { - log_warnx("host: interface name truncated"); - return (-1); - } - } - - TAILQ_INSERT_HEAD(al, h, entry); - return (1); - } - - return (host_dns(s, al, max, port, ifname)); -} diff --git a/usr.sbin/hostated/pfe.c b/usr.sbin/hostated/pfe.c deleted file mode 100644 index 573662922fd..00000000000 --- a/usr.sbin/hostated/pfe.c +++ /dev/null @@ -1,527 +0,0 @@ -/* $OpenBSD: pfe.c,v 1.5 2007/01/08 20:46:18 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/queue.h> -#include <sys/param.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <sys/socket.h> -#include <sys/un.h> -#include <net/if.h> -#include <errno.h> -#include <event.h> -#include <fcntl.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> -#include <pwd.h> - -#include "hostated.h" - -void pfe_sig_handler(int sig, short, void *); -void pfe_shutdown(void); -void pfe_dispatch_imsg(int, short, void *); -void pfe_dispatch_parent(int, short, void *); - -void pfe_sync(void); - -static struct hostated *env = NULL; - -struct imsgbuf *ibuf_main; -struct imsgbuf *ibuf_hce; - -void -pfe_sig_handler(int sig, short event, void *arg) -{ - switch (sig) { - case SIGINT: - case SIGTERM: - pfe_shutdown(); - default: - fatalx("pfe_sig_handler: unexpected signal"); - } -} - -pid_t -pfe(struct hostated *x_env, int pipe_parent2pfe[2], int pipe_parent2hce[2], - int pipe_pfe2hce[2]) -{ - pid_t pid; - struct passwd *pw; - struct event ev_sigint; - struct event ev_sigterm; - - switch (pid = fork()) { - case -1: - fatal("pfe: cannot fork"); - case 0: - break; - default: - return (pid); - } - - env = x_env; - - if (control_init() == -1) - fatalx("pfe: control socket setup failed"); - - init_filter(env); - init_tables(env); - - if ((pw = getpwnam(HOSTATED_USER)) == NULL) - fatal("pfe: getpwnam"); - - if (chroot(pw->pw_dir) == -1) - fatal("pfe: chroot"); - if (chdir("/") == -1) - fatal("pfe: chdir(\"/\")"); - - setproctitle("pf update engine"); - hostated_process = PROC_PFE; - - if (setgroups(1, &pw->pw_gid) || - setresgid(pw->pw_gid, pw->pw_gid, pw->pw_gid) || - setresuid(pw->pw_uid, pw->pw_uid, pw->pw_uid)) - fatal("pfe: cannot drop privileges"); - - event_init(); - - signal_set(&ev_sigint, SIGINT, pfe_sig_handler, NULL); - signal_set(&ev_sigterm, SIGTERM, pfe_sig_handler, NULL); - signal_add(&ev_sigint, NULL); - signal_add(&ev_sigterm, NULL); - - /* setup pipes */ - close(pipe_pfe2hce[0]); - close(pipe_parent2pfe[0]); - close(pipe_parent2hce[0]); - close(pipe_parent2hce[1]); - - if ((ibuf_hce = calloc(1, sizeof(struct imsgbuf))) == NULL || - (ibuf_main = calloc(1, sizeof(struct imsgbuf))) == NULL) - fatal("pfe"); - imsg_init(ibuf_hce, pipe_pfe2hce[1], pfe_dispatch_imsg); - imsg_init(ibuf_main, pipe_parent2pfe[1], pfe_dispatch_parent); - - ibuf_hce->events = EV_READ; - event_set(&ibuf_hce->ev, ibuf_hce->fd, ibuf_hce->events, - ibuf_hce->handler, ibuf_hce); - event_add(&ibuf_hce->ev, NULL); - - ibuf_main->events = EV_READ; - event_set(&ibuf_main->ev, ibuf_main->fd, ibuf_main->events, - ibuf_main->handler, ibuf_main); - event_add(&ibuf_main->ev, NULL); - - TAILQ_INIT(&ctl_conns); - control_listen(); - - event_dispatch(); - pfe_shutdown(); - - return (0); -} - -void -pfe_shutdown(void) -{ - flush_rulesets(env); - log_info("pf update engine exiting"); - _exit(0); -} - -void -pfe_dispatch_imsg(int fd, short event, void *ptr) -{ - struct imsgbuf *ibuf; - struct imsg imsg; - ssize_t n; - - struct host *host; - struct table *table; - struct ctl_status st; - - ibuf = ptr; - switch (event) { - case EV_READ: - if ((n = imsg_read(ibuf)) == -1) - fatal("pfe_dispatch_imsg: imsg_read_error"); - if (n == 0) - fatalx("pfe_dispatch_imsg: pipe closed"); - break; - case EV_WRITE: - if (msgbuf_write(&ibuf->w) == -1) - fatal("pfe_dispatch_imsg: msgbuf_write"); - imsg_event_add(ibuf); - return; - default: - fatalx("pfe_dispatch_imsg: unknown event"); - } - - for (;;) { - if ((n = imsg_get(ibuf, &imsg)) == -1) - fatal("pfe_dispatch_imsg: imsg_read error"); - if (n == 0) - break; - - switch (imsg.hdr.type) { - case IMSG_HOST_STATUS: - if (imsg.hdr.len - IMSG_HEADER_SIZE != sizeof(st)) - fatalx("pfe_dispatch_imsg: invalid request"); - memcpy(&st, imsg.data, sizeof(st)); - if ((host = host_find(env, st.id)) == NULL) - fatalx("pfe_dispatch_imsg: invalid host id"); - if (host->up == st.up) { - log_debug("pfe_dispatch_imsg: host %d => %d", - host->id, host->up); - fatalx("pfe_dispatch_imsg: desynchronized"); - } - - if ((table = table_find(env, host->tableid)) == NULL) - fatalx("pfe_dispatch_imsg: invalid table id"); - - log_debug("pfe_dispatch_imsg: state %d for host %u %s", - st.up, host->id, host->name); - - if ((st.up == HOST_UNKNOWN && host->up == HOST_DOWN) || - (st.up == HOST_DOWN && host->up == HOST_UNKNOWN)) { - host->up = st.up; - break; - } - - if (st.up == HOST_UP) { - table->flags |= F_CHANGED; - table->up++; - host->flags |= F_ADD; - host->flags &= ~(F_DEL); - } else { - table->up--; - table->flags |= F_CHANGED; - host->flags |= F_DEL; - host->flags &= ~(F_ADD); - } - host->up = st.up; - break; - case IMSG_SYNC: - pfe_sync(); - break; - default: - log_debug("pfe_dispatch_imsg: unexpected imsg %d", - imsg.hdr.type); - break; - } - imsg_free(&imsg); - } - imsg_event_add(ibuf); -} - -void -pfe_dispatch_parent(int fd, short event, void * ptr) -{ - struct imsgbuf *ibuf; - struct imsg imsg; - ssize_t n; - - ibuf = ptr; - switch (event) { - case EV_READ: - if ((n = imsg_read(ibuf)) == -1) - fatal("imsg_read error"); - if (n == 0) /* connection closed */ - fatalx("pfe_dispatch_parent: pipe closed"); - break; - case EV_WRITE: - if (msgbuf_write(&ibuf->w) == -1) - fatal("msgbuf_write"); - imsg_event_add(ibuf); - return; - default: - fatalx("pfe_dispatch_parent: unknown event"); - } - - for (;;) { - if ((n = imsg_get(ibuf, &imsg)) == -1) - fatal("pfe_dispatch_parent: imsg_read error"); - if (n == 0) - break; - - switch (imsg.hdr.type) { - default: - log_debug("pfe_dispatch_parent: unexpected imsg %d", - imsg.hdr.type); - break; - } - imsg_free(&imsg); - } -} - -void -show(struct ctl_conn *c) -{ - struct service *service; - struct host *host; - - TAILQ_FOREACH(service, &env->services, entry) { - imsg_compose(&c->ibuf, IMSG_CTL_SERVICE, 0, 0, - service, sizeof(*service)); - if (service->flags & F_DISABLE) - continue; - - imsg_compose(&c->ibuf, IMSG_CTL_TABLE, 0, 0, - service->table, sizeof(*service->table)); - if (!(service->table->flags & F_DISABLE)) - TAILQ_FOREACH(host, &service->table->hosts, entry) - imsg_compose(&c->ibuf, IMSG_CTL_HOST, 0, 0, - host, sizeof(*host)); - - if (service->backup->id == EMPTY_TABLE) - continue; - imsg_compose(&c->ibuf, IMSG_CTL_TABLE, 0, 0, - service->backup, sizeof(*service->backup)); - if (!(service->backup->flags & F_DISABLE)) - TAILQ_FOREACH(host, &service->backup->hosts, entry) - imsg_compose(&c->ibuf, IMSG_CTL_HOST, 0, 0, - host, sizeof(*host)); - } - imsg_compose(&c->ibuf, IMSG_CTL_END, 0, 0, NULL, 0); -} - - -int -disable_service(struct ctl_conn *c, struct ctl_id *id) -{ - struct service *service; - - if (id->id == EMPTY_ID) - service = service_findbyname(env, id->name); - else - service = service_find(env, id->id); - if (service == NULL) - return (-1); - - if (service->flags & F_DISABLE) - return (0); - - service->flags |= F_DISABLE; - service->flags &= ~(F_ADD); - service->flags |= F_DEL; - service->table->flags |= F_DISABLE; - log_debug("disable_service: disabled service %d", service->id); - pfe_sync(); - return (0); -} - -int -enable_service(struct ctl_conn *c, struct ctl_id *id) -{ - struct service *service; - struct ctl_id eid; - - if (id->id == EMPTY_ID) - service = service_findbyname(env, id->name); - else - service = service_find(env, id->id); - if (service == NULL) - return (-1); - - if (!(service->flags & F_DISABLE)) - return (0); - - service->flags &= ~(F_DISABLE); - service->flags &= ~(F_DEL); - service->flags |= F_ADD; - log_debug("enable_service: enabled service %d", service->id); - - bzero(&eid, sizeof(eid)); - - /* XXX: we're syncing twice */ - eid.id = service->table->id; - if (enable_table(c, &eid) == -1) - return (-1); - eid.id = service->backup->id; - if (enable_table(c, &eid) == -1) - return (-1); - return (0); -} - -int -disable_table(struct ctl_conn *c, struct ctl_id *id) -{ - struct table *table; - struct service *service; - struct host *host; - - if (id->id == EMPTY_ID) - table = table_findbyname(env, id->name); - else - table = table_find(env, id->id); - if (table == NULL) - return (-1); - if ((service = service_find(env, table->serviceid)) == NULL) - fatalx("disable_table: desynchronised"); - - if (table->flags & F_DISABLE) - return (0); - table->flags |= (F_DISABLE|F_CHANGED); - table->up = 0; - TAILQ_FOREACH(host, &table->hosts, entry) - host->up = HOST_UNKNOWN; - imsg_compose(ibuf_hce, IMSG_TABLE_DISABLE, 0, 0, - &table->id, sizeof(table->id)); - log_debug("disable_table: disabled table %d", table->id); - pfe_sync(); - return (0); -} - -int -enable_table(struct ctl_conn *c, struct ctl_id *id) -{ - struct service *service; - struct table *table; - struct host *host; - - if (id->id == EMPTY_ID) - table = table_findbyname(env, id->name); - else - table = table_find(env, id->id); - if (table == NULL) - return (-1); - - if ((service = service_find(env, table->serviceid)) == NULL) - fatalx("enable_table: desynchronised"); - - if (!(table->flags & F_DISABLE)) - return (0); - table->flags &= ~(F_DISABLE); - table->flags |= F_CHANGED; - table->up = 0; - TAILQ_FOREACH(host, &table->hosts, entry) - host->up = HOST_UNKNOWN; - imsg_compose(ibuf_hce, IMSG_TABLE_ENABLE, 0, 0, - &table->id, sizeof(table->id)); - log_debug("enable_table: enabled table %d", table->id); - pfe_sync(); - return (0); -} - -int -disable_host(struct ctl_conn *c, struct ctl_id *id) -{ - struct host *host; - struct table *table; - - if (id->id == EMPTY_ID) - host = host_findbyname(env, id->name); - else - host = host_find(env, id->id); - if (host == NULL) - return (-1); - - if (host->flags & F_DISABLE) - return (0); - - if (host->up == HOST_UP) { - if ((table = table_find(env, host->tableid)) == NULL) - fatalx("disable_host: invalid table id"); - table->up--; - table->flags |= F_CHANGED; - } - - host->up = HOST_UNKNOWN; - host->flags |= F_DISABLE; - host->flags |= F_DEL; - host->flags &= ~(F_ADD); - - imsg_compose(ibuf_hce, IMSG_HOST_DISABLE, 0, 0, - &host->id, sizeof(host->id)); - log_debug("disable_host: disabled host %d", host->id); - pfe_sync(); - return (0); -} - -int -enable_host(struct ctl_conn *c, struct ctl_id *id) -{ - struct host *host; - - if (id->id == EMPTY_ID) - host = host_findbyname(env, id->name); - else - host = host_find(env, id->id); - if (host == NULL) - return (-1); - - if (!(host->flags & F_DISABLE)) - return (0); - - host->up = HOST_UNKNOWN; - host->flags &= ~(F_DISABLE); - host->flags &= ~(F_DEL); - host->flags &= ~(F_ADD); - - imsg_compose(ibuf_hce, IMSG_HOST_ENABLE, 0, 0, - &host->id, sizeof (host->id)); - log_debug("enable_host: enabled host %d", host->id); - pfe_sync(); - return (0); -} - -void -pfe_sync(void) -{ - struct service *service; - struct table *active; - int backup; - - TAILQ_FOREACH(service, &env->services, entry) { - backup = (service->flags & F_BACKUP); - service->flags &= ~(F_BACKUP); - service->flags &= ~(F_DOWN); - - if (service->flags & F_DISABLE || - (service->table->up == 0 && service->backup->up == 0)) { - service->flags |= F_DOWN; - active = NULL; - } else if (service->table->up == 0 && service->backup->up > 0) { - service->flags |= F_BACKUP; - active = service->backup; - active->flags |= service->table->flags & F_CHANGED; - active->flags |= service->backup->flags & F_CHANGED; - } else - active = service->table; - - if (active != NULL && active->flags & F_CHANGED) - sync_table(env, service, active); - - service->table->flags &= ~(F_CHANGED); - service->backup->flags &= ~(F_CHANGED); - - if (service->flags & F_DOWN) { - if (service->flags & F_ACTIVE_RULESET) { - flush_table(env, service); - log_debug("pfe_sync: disabling ruleset"); - service->flags &= ~(F_ACTIVE_RULESET); - sync_ruleset(env, service, 0); - } - } else if (!(service->flags & F_ACTIVE_RULESET)) { - log_debug("pfe_sync: enabling ruleset"); - service->flags |= F_ACTIVE_RULESET; - sync_ruleset(env, service, 1); - } - } -} diff --git a/usr.sbin/hostated/pfe_filter.c b/usr.sbin/hostated/pfe_filter.c deleted file mode 100644 index 4e80d6dc412..00000000000 --- a/usr.sbin/hostated/pfe_filter.c +++ /dev/null @@ -1,342 +0,0 @@ -/* $OpenBSD: pfe_filter.c,v 1.7 2007/01/08 20:46:18 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/ioctl.h> -#include <sys/param.h> - -#include <net/if.h> -#include <net/pfvar.h> -#include <netinet/in.h> -#include <arpa/inet.h> - -#include <limits.h> -#include <fcntl.h> -#include <event.h> -#include <string.h> -#include <stdio.h> -#include <stdlib.h> -#include <errno.h> - -#include "hostated.h" - -struct pfdata { - int dev; - struct pf_anchor *anchor; - struct pfioc_trans pft; - struct pfioc_trans_e pfte; -}; - -int transaction_init(struct hostated *, const char *); -int transaction_commit(struct hostated *); -void kill_tables(struct hostated *); - -void -init_filter(struct hostated *env) -{ - struct pf_status status; - - if ((env->pf = calloc(1, sizeof(*(env->pf)))) == NULL) - fatal("calloc"); - if ((env->pf->dev = open(PF_SOCKET, O_RDWR)) == -1) - fatal("init_filter: cannot open pf socket"); - if (ioctl(env->pf->dev, DIOCGETSTATUS, &status) == -1) - fatal("init_filter: DIOCGETSTATUS"); - if (!status.running) - fatalx("init_filter: pf is disabled"); - log_debug("init_filter: filter init done"); -} - -void -init_tables(struct hostated *env) -{ - int i; - struct service *service; - struct pfr_table *tables; - struct pfioc_table io; - - if ((tables = calloc(env->servicecount, sizeof(*tables))) == NULL) - fatal("calloc"); - i = 0; - - TAILQ_FOREACH(service, &env->services, entry) { - (void)strlcpy(tables[i].pfrt_anchor, HOSTATED_ANCHOR "/", - sizeof(tables[i].pfrt_anchor)); - (void)strlcat(tables[i].pfrt_anchor, service->name, - sizeof(tables[i].pfrt_anchor)); - (void)strlcpy(tables[i].pfrt_name, service->name, - sizeof(tables[i].pfrt_name)); - tables[i].pfrt_flags |= PFR_TFLAG_PERSIST; - i++; - } - if (i != env->servicecount) - fatalx("init_tables: table count modified"); - - memset(&io, 0, sizeof(io)); - io.pfrio_size = env->servicecount; - io.pfrio_esize = sizeof(*tables); - io.pfrio_buffer = tables; - - if (ioctl(env->pf->dev, DIOCRADDTABLES, &io) == -1) - fatal("init_tables: cannot create tables"); - log_debug("created %d tables", io.pfrio_nadd); - - free(tables); - - if (io.pfrio_nadd == env->servicecount) - return; - - /* - * clear all tables, since some already existed - */ - TAILQ_FOREACH(service, &env->services, entry) - flush_table(env, service); -} - -void -kill_tables(struct hostated *env) { - struct pfioc_table io; - struct service *service; - - memset(&io, 0, sizeof(io)); - TAILQ_FOREACH(service, &env->services, entry) { - (void)strlcpy(io.pfrio_table.pfrt_anchor, HOSTATED_ANCHOR "/", - sizeof(io.pfrio_table.pfrt_anchor)); - (void)strlcat(io.pfrio_table.pfrt_anchor, service->name, - sizeof(io.pfrio_table.pfrt_anchor)); - if (ioctl(env->pf->dev, DIOCRCLRTABLES, &io) == -1) - fatal("kill_tables: ioctl faile: ioctl failed"); - } - log_debug("kill_tables: deleted %d tables", io.pfrio_ndel); -} - -void -sync_table(struct hostated *env, struct service *service, struct table *table) -{ - int i; - struct pfioc_table io; - struct pfr_addr *addlist; - struct sockaddr_in *sain; - struct sockaddr_in6 *sain6; - struct host *host; - - if (table == NULL) - return; - - if (table->up == 0) { - flush_table(env, service); - return; - } - - if ((addlist = calloc(table->up, sizeof(*addlist))) == NULL) - fatal("calloc"); - - memset(&io, 0, sizeof(io)); - io.pfrio_esize = sizeof(struct pfr_addr); - io.pfrio_size = table->up; - io.pfrio_size2 = 0; - io.pfrio_buffer = addlist; - (void)strlcpy(io.pfrio_table.pfrt_anchor, HOSTATED_ANCHOR "/", - sizeof(io.pfrio_table.pfrt_anchor)); - (void)strlcat(io.pfrio_table.pfrt_anchor, service->name, - sizeof(io.pfrio_table.pfrt_anchor)); - (void)strlcpy(io.pfrio_table.pfrt_name, service->name, - sizeof(io.pfrio_table.pfrt_name)); - - i = 0; - TAILQ_FOREACH(host, &table->hosts, entry) { - if (host->up != 1) - continue; - memset(&(addlist[i]), 0, sizeof(addlist[i])); - switch (host->ss.ss_family) { - case AF_INET: - sain = (struct sockaddr_in *)&host->ss; - addlist[i].pfra_af = AF_INET; - memcpy(&(addlist[i].pfra_ip4addr), &sain->sin_addr, - sizeof(sain->sin_addr)); - addlist[i].pfra_net = 32; - break; - case AF_INET6: - sain6 = (struct sockaddr_in6 *)&host->ss; - addlist[i].pfra_af = AF_INET6; - memcpy(&(addlist[i].pfra_ip6addr), &sain6->sin6_addr, - sizeof(sain6->sin6_addr)); - addlist[i].pfra_net = 128; - break; - default: - fatalx("sync_table: unknown address family"); - break; - } - i++; - } - if (i != table->up) - fatalx("sync_table: desynchronized"); - - if (ioctl(env->pf->dev, DIOCRSETADDRS, &io) == -1) - fatal("sync_table: cannot set address list"); - - free(addlist); - - log_debug("sync_table: table %s: %d added, %d deleted, %d changed", - io.pfrio_table.pfrt_name, - io.pfrio_nadd, io.pfrio_ndel, io.pfrio_nchange); -} - -void -flush_table(struct hostated *env, struct service *service) -{ - struct pfioc_table io; - - memset(&io, 0, sizeof(io)); - (void)strlcpy(io.pfrio_table.pfrt_anchor, HOSTATED_ANCHOR "/", - sizeof(io.pfrio_table.pfrt_anchor)); - (void)strlcat(io.pfrio_table.pfrt_anchor, service->name, - sizeof(io.pfrio_table.pfrt_anchor)); - (void)strlcpy(io.pfrio_table.pfrt_name, service->name, - sizeof(io.pfrio_table.pfrt_name)); - if (ioctl(env->pf->dev, DIOCRCLRADDRS, &io) == -1) - fatal("flush_table: cannot flush table"); - log_debug("flush_table: flushed table %s", service->name); - return; -} - -int -transaction_init(struct hostated *env, const char *anchor) -{ - env->pf->pft.size = 1; - env->pf->pft.esize = sizeof env->pf->pfte; - env->pf->pft.array = &env->pf->pfte; - - memset(&env->pf->pfte, 0, sizeof env->pf->pfte); - strlcpy(env->pf->pfte.anchor, anchor, PF_ANCHOR_NAME_SIZE); - env->pf->pfte.rs_num = PF_RULESET_RDR; - - if (ioctl(env->pf->dev, DIOCXBEGIN, &env->pf->pft) == -1) - return (-1); - return (0); -} - -int -transaction_commit(struct hostated *env) -{ - if (ioctl(env->pf->dev, DIOCXCOMMIT, &env->pf->pft) == -1) - return (-1); - return (0); -} - -void -sync_ruleset(struct hostated *env, struct service *service, int enable) -{ - struct pfioc_rule rio; - struct pfioc_pooladdr pio; - struct sockaddr_in *sain; - struct sockaddr_in6 *sain6; - struct address *address; - char anchor[PF_ANCHOR_NAME_SIZE]; - - bzero(anchor, sizeof(anchor)); - (void)strlcpy(anchor, HOSTATED_ANCHOR "/", sizeof(anchor)); - (void)strlcat(anchor, service->name, sizeof(anchor)); - transaction_init(env, anchor); - - if (!enable) { - transaction_commit(env); - log_debug("sync_ruleset: rules removed"); - return; - } - - TAILQ_FOREACH(address, &service->virts, entry) { - memset(&rio, 0, sizeof(rio)); - memset(&pio, 0, sizeof(pio)); - (void)strlcpy(rio.anchor, anchor, sizeof(rio.anchor)); - - rio.ticket = env->pf->pfte.ticket; - if (ioctl(env->pf->dev, DIOCBEGINADDRS, &pio) == -1) - fatal("sync_ruleset: cannot initialise address pool"); - - rio.pool_ticket = pio.ticket; - rio.rule.af = address->ss.ss_family; - rio.rule.proto = IPPROTO_TCP; - rio.rule.src.addr.type = PF_ADDR_ADDRMASK; - rio.rule.dst.addr.type = PF_ADDR_ADDRMASK; - rio.rule.dst.port_op = PF_OP_EQ; - rio.rule.dst.port[0] = address->port; - rio.rule.rtableid = -1; /* stay in the main routing table */ - rio.rule.action = PF_RDR; - if (strlen(service->tag)) - (void)strlcpy(rio.rule.tagname, service->tag, - sizeof(rio.rule.tagname)); - if (strlen(address->ifname)) - (void)strlcpy(rio.rule.ifname, address->ifname, - sizeof(rio.rule.ifname)); - - if (address->ss.ss_family == AF_INET) { - sain = (struct sockaddr_in *)&address->ss; - - rio.rule.dst.addr.v.a.addr.addr32[0] = - sain->sin_addr.s_addr; - rio.rule.dst.addr.v.a.mask.addr32[0] = 0xffffffff; - - } else { - sain6 = (struct sockaddr_in6 *)&address->ss; - - memcpy(&rio.rule.dst.addr.v.a.addr.v6, - &sain6->sin6_addr.s6_addr, - sizeof(sain6->sin6_addr.s6_addr)); - memset(&rio.rule.dst.addr.v.a.mask.addr8, 0xff, 16); - } - - pio.addr.addr.type = PF_ADDR_TABLE; - (void)strlcpy(pio.addr.addr.v.tblname, service->name, - sizeof(pio.addr.addr.v.tblname)); - if (ioctl(env->pf->dev, DIOCADDADDR, &pio) == -1) - fatal("sync_ruleset: cannot add address to pool"); - - rio.rule.rpool.proxy_port[0] = ntohs(service->table->port); - rio.rule.rpool.port_op = PF_OP_EQ; - rio.rule.rpool.opts = PF_POOL_ROUNDROBIN; - if (service->flags & F_STICKY) - rio.rule.rpool.opts |= PF_POOL_STICKYADDR; - - if (ioctl(env->pf->dev, DIOCADDRULE, &rio) == -1) - fatal("cannot add rule"); - log_debug("sync_ruleset: rule added"); - } - transaction_commit(env); -} - -void -flush_rulesets(struct hostated *env) -{ - struct service *service; - char anchor[PF_ANCHOR_NAME_SIZE]; - - kill_tables(env); - TAILQ_FOREACH(service, &env->services, entry) { - strlcpy(anchor, HOSTATED_ANCHOR "/", sizeof(anchor)); - strlcat(anchor, service->name, sizeof(anchor)); - transaction_init(env, anchor); - transaction_commit(env); - } - strlcpy(anchor, HOSTATED_ANCHOR, sizeof(anchor)); - transaction_init(env, anchor); - transaction_commit(env); - log_debug("flush_rulesets: flushed rules"); -} |