main.c revision 52419
152419Sjulian
252419Sjulian/*
352419Sjulian * main.c
452419Sjulian *
552419Sjulian * Copyright (c) 1996-1999 Whistle Communications, Inc.
652419Sjulian * All rights reserved.
752419Sjulian *
852419Sjulian * Subject to the following obligations and disclaimer of warranty, use and
952419Sjulian * redistribution of this software, in source or object code forms, with or
1052419Sjulian * without modifications are expressly permitted by Whistle Communications;
1152419Sjulian * provided, however, that:
1252419Sjulian * 1. Any and all reproductions of the source or object code must include the
1352419Sjulian *    copyright notice above and the following disclaimer of warranties; and
1452419Sjulian * 2. No rights are granted, in any manner or form, to use Whistle
1552419Sjulian *    Communications, Inc. trademarks, including the mark "WHISTLE
1652419Sjulian *    COMMUNICATIONS" on advertising, endorsements, or otherwise except as
1752419Sjulian *    such appears in the above copyright notice or in the software.
1852419Sjulian *
1952419Sjulian * THIS SOFTWARE IS BEING PROVIDED BY WHISTLE COMMUNICATIONS "AS IS", AND
2052419Sjulian * TO THE MAXIMUM EXTENT PERMITTED BY LAW, WHISTLE COMMUNICATIONS MAKES NO
2152419Sjulian * REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED, REGARDING THIS SOFTWARE,
2252419Sjulian * INCLUDING WITHOUT LIMITATION, ANY AND ALL IMPLIED WARRANTIES OF
2352419Sjulian * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT.
2452419Sjulian * WHISTLE COMMUNICATIONS DOES NOT WARRANT, GUARANTEE, OR MAKE ANY
2552419Sjulian * REPRESENTATIONS REGARDING THE USE OF, OR THE RESULTS OF THE USE OF THIS
2652419Sjulian * SOFTWARE IN TERMS OF ITS CORRECTNESS, ACCURACY, RELIABILITY OR OTHERWISE.
2752419Sjulian * IN NO EVENT SHALL WHISTLE COMMUNICATIONS BE LIABLE FOR ANY DAMAGES
2852419Sjulian * RESULTING FROM OR ARISING OUT OF ANY USE OF THIS SOFTWARE, INCLUDING
2952419Sjulian * WITHOUT LIMITATION, ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
3052419Sjulian * PUNITIVE, OR CONSEQUENTIAL DAMAGES, PROCUREMENT OF SUBSTITUTE GOODS OR
3152419Sjulian * SERVICES, LOSS OF USE, DATA OR PROFITS, HOWEVER CAUSED AND UNDER ANY
3252419Sjulian * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
3352419Sjulian * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
3452419Sjulian * THIS SOFTWARE, EVEN IF WHISTLE COMMUNICATIONS IS ADVISED OF THE POSSIBILITY
3552419Sjulian * OF SUCH DAMAGE.
3652419Sjulian *
3752419Sjulian * $FreeBSD: head/usr.sbin/nghook/main.c 52419 1999-10-21 09:06:11Z julian $
3852419Sjulian * $Whistle: main.c,v 1.9 1999/01/20 00:26:26 archie Exp $
3952419Sjulian */
4052419Sjulian
4152419Sjulian#include <stdio.h>
4252419Sjulian#include <stdlib.h>
4352419Sjulian#include <string.h>
4452419Sjulian#include <ctype.h>
4552419Sjulian#include <unistd.h>
4652419Sjulian#include <sysexits.h>
4752419Sjulian#include <errno.h>
4852419Sjulian#include <err.h>
4952419Sjulian
5052419Sjulian#include <sys/types.h>
5152419Sjulian#include <sys/socket.h>
5252419Sjulian#include <sys/select.h>
5352419Sjulian
5452419Sjulian#include <netgraph.h>
5552419Sjulian
5652419Sjulian#define DEFAULT_HOOKNAME	"debug"
5752419Sjulian#define NG_SOCK_HOOK_NAME	"hook"
5852419Sjulian
5952419Sjulian#define BUF_SIZE		(64 * 1024)
6052419Sjulian
6152419Sjulianstatic void	WriteAscii(u_char * buf, int len);
6252419Sjulianstatic void	Usage(void);
6352419Sjulian
6452419Sjulian/*
6552419Sjulian * main()
6652419Sjulian */
6752419Sjulianint
6852419Sjulianmain(int ac, char *av[])
6952419Sjulian{
7052419Sjulian	struct ngm_connect ngc;
7152419Sjulian	char   *path = NULL, *hook = DEFAULT_HOOKNAME;
7252419Sjulian	int     csock, dsock;
7352419Sjulian	int     asciiFlag = 0;
7452419Sjulian	int	ch;
7552419Sjulian
7652419Sjulian	/* Parse flags */
7752419Sjulian	while ((ch = getopt(ac, av, "da")) != EOF) {
7852419Sjulian		switch (ch) {
7952419Sjulian		case 'd':
8052419Sjulian			NgSetDebug(NgSetDebug(-1) + 1);
8152419Sjulian			break;
8252419Sjulian		case 'a':
8352419Sjulian			asciiFlag = 1;
8452419Sjulian			break;
8552419Sjulian		case '?':
8652419Sjulian		default:
8752419Sjulian			Usage();
8852419Sjulian		}
8952419Sjulian	}
9052419Sjulian	ac -= optind;
9152419Sjulian	av += optind;
9252419Sjulian
9352419Sjulian	/* Get params */
9452419Sjulian	switch (ac) {
9552419Sjulian	case 2:
9652419Sjulian		hook = av[1];
9752419Sjulian		/* FALLTHROUGH */
9852419Sjulian	case 1:
9952419Sjulian		path = av[0];
10052419Sjulian		break;
10152419Sjulian	default:
10252419Sjulian		Usage();
10352419Sjulian	}
10452419Sjulian
10552419Sjulian	/* Get sockets */
10652419Sjulian	if (NgMkSockNode(NULL, &csock, &dsock) < 0)
10752419Sjulian		errx(EX_OSERR, "can't get sockets");
10852419Sjulian
10952419Sjulian	/* Connect socket node to specified node */
11052419Sjulian	snprintf(ngc.path, sizeof(ngc.path), "%s", path);
11152419Sjulian	snprintf(ngc.ourhook, sizeof(ngc.ourhook), NG_SOCK_HOOK_NAME);
11252419Sjulian	snprintf(ngc.peerhook, sizeof(ngc.peerhook), "%s", hook);
11352419Sjulian
11452419Sjulian	if (NgSendMsg(csock, ".",
11552419Sjulian	    NGM_GENERIC_COOKIE, NGM_CONNECT, &ngc, sizeof(ngc)) < 0)
11652419Sjulian		errx(EX_OSERR, "can't connect to node");
11752419Sjulian
11852419Sjulian	/* Relay data */
11952419Sjulian	while (1) {
12052419Sjulian		fd_set  rfds;
12152419Sjulian
12252419Sjulian		/* Setup bits */
12352419Sjulian		FD_ZERO(&rfds);
12452419Sjulian		FD_SET(0, &rfds);
12552419Sjulian		FD_SET(dsock, &rfds);
12652419Sjulian
12752419Sjulian		/* Wait for something to happen */
12852419Sjulian		if (select(FD_SETSIZE, &rfds, NULL, NULL, NULL) < 0)
12952419Sjulian			err(EX_OSERR, "select");
13052419Sjulian
13152419Sjulian		/* Check data from socket */
13252419Sjulian		if (FD_ISSET(dsock, &rfds)) {
13352419Sjulian			char    buf[BUF_SIZE];
13452419Sjulian			int     rl, wl;
13552419Sjulian
13652419Sjulian			/* Read packet from socket */
13752419Sjulian			if ((rl = NgRecvData(dsock,
13852419Sjulian			    buf, sizeof(buf), NULL)) < 0)
13952419Sjulian				err(EX_OSERR, "read(hook)");
14052419Sjulian			if (rl == 0)
14152419Sjulian				errx(EX_OSERR, "read EOF from hook?!");
14252419Sjulian
14352419Sjulian			/* Write packet to stdout */
14452419Sjulian			if (asciiFlag)
14552419Sjulian				WriteAscii((u_char *) buf, rl);
14652419Sjulian			else if ((wl = write(1, buf, rl)) != rl) {
14752419Sjulian				if (wl < 0) {
14852419Sjulian					err(EX_OSERR, "write(stdout)");
14952419Sjulian				} else {
15052419Sjulian					errx(EX_OSERR,
15152419Sjulian					    "stdout: read %d, wrote %d",
15252419Sjulian					    rl, wl);
15352419Sjulian				}
15452419Sjulian			}
15552419Sjulian		}
15652419Sjulian
15752419Sjulian		/* Check data from stdin */
15852419Sjulian		if (FD_ISSET(0, &rfds)) {
15952419Sjulian			char    buf[BUF_SIZE];
16052419Sjulian			int     rl;
16152419Sjulian
16252419Sjulian			/* Read packet from stdin */
16352419Sjulian			if ((rl = read(0, buf, sizeof(buf))) < 0)
16452419Sjulian				err(EX_OSERR, "read(stdin)");
16552419Sjulian			if (rl == 0)
16652419Sjulian				errx(EX_OSERR, "EOF(stdin)");
16752419Sjulian
16852419Sjulian			/* Write packet to socket */
16952419Sjulian			if (NgSendData(dsock, NG_SOCK_HOOK_NAME, buf, rl) < 0)
17052419Sjulian				err(EX_OSERR, "write(hook)");
17152419Sjulian		}
17252419Sjulian	}
17352419Sjulian}
17452419Sjulian
17552419Sjulian/*
17652419Sjulian * Dump data in hex and ASCII form
17752419Sjulian */
17852419Sjulianstatic void
17952419SjulianWriteAscii(u_char *buf, int len)
18052419Sjulian{
18152419Sjulian	char    ch, sbuf[100];
18252419Sjulian	int     k, count;
18352419Sjulian
18452419Sjulian	for (count = 0; count < len; count += 16) {
18552419Sjulian		snprintf(sbuf, sizeof(sbuf), "%04x:  ", count);
18652419Sjulian		for (k = 0; k < 16; k++)
18752419Sjulian			if (count + k < len)
18852419Sjulian				snprintf(sbuf + strlen(sbuf),
18952419Sjulian				    sizeof(sbuf) - strlen(sbuf),
19052419Sjulian				    "%02x ", buf[count + k]);
19152419Sjulian			else
19252419Sjulian				snprintf(sbuf + strlen(sbuf),
19352419Sjulian				    sizeof(sbuf) - strlen(sbuf), "   ");
19452419Sjulian		snprintf(sbuf + strlen(sbuf), sizeof(sbuf) - strlen(sbuf), " ");
19552419Sjulian		for (k = 0; k < 16; k++)
19652419Sjulian			if (count + k < len) {
19752419Sjulian				ch = isprint(buf[count + k]) ?
19852419Sjulian				    buf[count + k] : '.';
19952419Sjulian				snprintf(sbuf + strlen(sbuf),
20052419Sjulian				    sizeof(sbuf) - strlen(sbuf), "%c", ch);
20152419Sjulian			} else
20252419Sjulian				snprintf(sbuf + strlen(sbuf),
20352419Sjulian				    sizeof(sbuf) - strlen(sbuf), "   ");
20452419Sjulian		snprintf(sbuf + strlen(sbuf),
20552419Sjulian		    sizeof(sbuf) - strlen(sbuf), "\n");
20652419Sjulian		(void) write(1, sbuf, strlen(sbuf));
20752419Sjulian	}
20852419Sjulian	ch = '\n';
20952419Sjulian	write(1, &ch, 1);
21052419Sjulian}
21152419Sjulian
21252419Sjulian/*
21352419Sjulian * Display usage and exit
21452419Sjulian */
21552419Sjulianstatic void
21652419SjulianUsage(void)
21752419Sjulian{
21852419Sjulian	errx(EX_USAGE, "usage: nghook [-da] path [hookname]");
21952419Sjulian}
22052419Sjulian
221