diff options
Diffstat (limited to 'usr.sbin/nghook')
-rw-r--r-- | usr.sbin/nghook/Makefile | 11 | ||||
-rw-r--r-- | usr.sbin/nghook/main.c | 309 | ||||
-rw-r--r-- | usr.sbin/nghook/nghook.8 | 145 |
3 files changed, 465 insertions, 0 deletions
diff --git a/usr.sbin/nghook/Makefile b/usr.sbin/nghook/Makefile new file mode 100644 index 0000000..e427f26 --- /dev/null +++ b/usr.sbin/nghook/Makefile @@ -0,0 +1,11 @@ +# $FreeBSD$ +# $Whistle: Makefile,v 1.4 1999/01/16 04:44:33 archie Exp $ + +PROG= nghook +MAN= nghook.8 +SRCS= main.c + +DPADD= ${LIBNETGRAPH} +LDADD= -lnetgraph + +.include <bsd.prog.mk> diff --git a/usr.sbin/nghook/main.c b/usr.sbin/nghook/main.c new file mode 100644 index 0000000..700ca5e --- /dev/null +++ b/usr.sbin/nghook/main.c @@ -0,0 +1,309 @@ +/* + * main.c + * + * Copyright (c) 1996-1999 Whistle Communications, Inc. + * All rights reserved. + * + * Subject to the following obligations and disclaimer of warranty, use and + * redistribution of this software, in source or object code forms, with or + * without modifications are expressly permitted by Whistle Communications; + * provided, however, that: + * 1. Any and all reproductions of the source or object code must include the + * copyright notice above and the following disclaimer of warranties; and + * 2. No rights are granted, in any manner or form, to use Whistle + * Communications, Inc. trademarks, including the mark "WHISTLE + * COMMUNICATIONS" on advertising, endorsements, or otherwise except as + * such appears in the above copyright notice or in the software. + * + * THIS SOFTWARE IS BEING PROVIDED BY WHISTLE COMMUNICATIONS "AS IS", AND + * TO THE MAXIMUM EXTENT PERMITTED BY LAW, WHISTLE COMMUNICATIONS MAKES NO + * REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED, REGARDING THIS SOFTWARE, + * INCLUDING WITHOUT LIMITATION, ANY AND ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT. + * WHISTLE COMMUNICATIONS DOES NOT WARRANT, GUARANTEE, OR MAKE ANY + * REPRESENTATIONS REGARDING THE USE OF, OR THE RESULTS OF THE USE OF THIS + * SOFTWARE IN TERMS OF ITS CORRECTNESS, ACCURACY, RELIABILITY OR OTHERWISE. + * IN NO EVENT SHALL WHISTLE COMMUNICATIONS BE LIABLE FOR ANY DAMAGES + * RESULTING FROM OR ARISING OUT OF ANY USE OF THIS SOFTWARE, INCLUDING + * WITHOUT LIMITATION, ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, + * PUNITIVE, OR CONSEQUENTIAL DAMAGES, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES, LOSS OF USE, DATA OR PROFITS, HOWEVER CAUSED AND UNDER 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 WHISTLE COMMUNICATIONS IS ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * $Whistle: main.c,v 1.9 1999/01/20 00:26:26 archie Exp $ + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <ctype.h> +#include <unistd.h> +#include <sysexits.h> +#include <errno.h> +#include <err.h> +#include <stringlist.h> + +#include <sys/types.h> +#include <sys/socket.h> +#include <sys/select.h> + +#include <netgraph.h> + +#define DEFAULT_HOOKNAME "debug" +#define NG_SOCK_HOOK_NAME "hook" + +#define BUF_SIZE (64 * 1024) + +static void WriteAscii(u_char * buf, int len); +static void Usage(void); +static void send_msgs(int, const char *); + +static int outfd = STDOUT_FILENO; +static int infd = STDIN_FILENO; + +static StringList *msgs; + +/* + * main() + */ +int +main(int ac, char *av[]) +{ + struct ngm_connect ngc; + const char *path = NULL; + const char *hook = DEFAULT_HOOKNAME; + int csock, dsock; + int asciiFlag = 0; + int loopFlag = 0; + int noInput = 0; + int execFlag = 0; + int ch; + + if ((msgs = sl_init()) == NULL) + err(EX_OSERR, NULL); + + /* Parse flags */ + while ((ch = getopt(ac, av, "aedlm:nsS")) != -1) { + switch (ch) { + case 'a': + asciiFlag = 1; + break; + case 'd': + NgSetDebug(NgSetDebug(-1) + 1); + break; + case 'e': + execFlag = 1; + break; + case 'l': + loopFlag = 1; + break; + case 'n': + noInput = 1; + break; + case 'm': + if (sl_add(msgs, optarg) == -1) + err(EX_OSERR, NULL); + break; + case 's': + outfd = STDIN_FILENO; + break; + case 'S': + infd = STDOUT_FILENO; + break; + case '?': + default: + Usage(); + } + } + ac -= optind; + av += optind; + + if (execFlag) { + if (asciiFlag || loopFlag) { + fprintf(stderr, "conflicting options\n"); + Usage(); + } + if (ac < 3) + Usage(); + path = av[0]; + hook = av[1]; + av += 2; + ac -= 2; + } else { + /* Get params */ + switch (ac) { + case 2: + hook = av[1]; + /* FALLTHROUGH */ + case 1: + path = av[0]; + break; + default: + Usage(); + } + } + + /* Get sockets */ + if (NgMkSockNode(NULL, &csock, &dsock) < 0) + errx(EX_OSERR, "can't get sockets"); + + /* Connect socket node to specified node */ + snprintf(ngc.path, sizeof(ngc.path), "%s", path); + snprintf(ngc.ourhook, sizeof(ngc.ourhook), NG_SOCK_HOOK_NAME); + snprintf(ngc.peerhook, sizeof(ngc.peerhook), "%s", hook); + + if (NgSendMsg(csock, ".", + NGM_GENERIC_COOKIE, NGM_CONNECT, &ngc, sizeof(ngc)) < 0) + errx(EX_OSERR, "can't connect to node"); + + if (execFlag) { + /* move dsock to fd 0 and 1 */ + (void)close(0); + (void)close(1); + if (!noInput) + (void)dup2(dsock, 0); + (void)dup2(dsock, 1); + + send_msgs(csock, path); + + /* try executing the program */ + (void)execv(av[0], av); + err(EX_OSERR, "%s", av[0]); + + } else + send_msgs(csock, path); + + /* Close standard input if not reading from it */ + if (noInput) + fclose(stdin); + + /* Relay data */ + while (1) { + fd_set rfds; + + /* Setup bits */ + FD_ZERO(&rfds); + if (!noInput) + FD_SET(infd, &rfds); + FD_SET(dsock, &rfds); + + /* Wait for something to happen */ + if (select(FD_SETSIZE, &rfds, NULL, NULL, NULL) < 0) + err(EX_OSERR, "select"); + + /* Check data from socket */ + if (FD_ISSET(dsock, &rfds)) { + char buf[BUF_SIZE]; + int rl, wl; + + /* Read packet from socket */ + if ((rl = NgRecvData(dsock, + buf, sizeof(buf), NULL)) < 0) + err(EX_OSERR, "read(hook)"); + if (rl == 0) + errx(EX_OSERR, "read EOF from hook?!"); + + /* Write packet to stdout */ + if (asciiFlag) + WriteAscii((u_char *) buf, rl); + else if ((wl = write(outfd, buf, rl)) != rl) { + if (wl < 0) { + err(EX_OSERR, "write(stdout)"); + } else { + errx(EX_OSERR, + "stdout: read %d, wrote %d", + rl, wl); + } + } + /* Loopback */ + if (loopFlag) { + if (NgSendData(dsock, NG_SOCK_HOOK_NAME, buf, rl) < 0) + err(EX_OSERR, "write(hook)"); + } + } + + /* Check data from stdin */ + if (FD_ISSET(infd, &rfds)) { + char buf[BUF_SIZE]; + int rl; + + /* Read packet from stdin */ + if ((rl = read(infd, buf, sizeof(buf))) < 0) + err(EX_OSERR, "read(stdin)"); + if (rl == 0) + errx(EX_OSERR, "EOF(stdin)"); + + /* Write packet to socket */ + if (NgSendData(dsock, NG_SOCK_HOOK_NAME, buf, rl) < 0) + err(EX_OSERR, "write(hook)"); + } + } +} + +/* + * Dump data in hex and ASCII form + */ +static void +WriteAscii(u_char *buf, int len) +{ + char ch, sbuf[100]; + int k, count; + + for (count = 0; count < len; count += 16) { + snprintf(sbuf, sizeof(sbuf), "%04x: ", count); + for (k = 0; k < 16; k++) + if (count + k < len) + snprintf(sbuf + strlen(sbuf), + sizeof(sbuf) - strlen(sbuf), + "%02x ", buf[count + k]); + else + snprintf(sbuf + strlen(sbuf), + sizeof(sbuf) - strlen(sbuf), " "); + snprintf(sbuf + strlen(sbuf), sizeof(sbuf) - strlen(sbuf), " "); + for (k = 0; k < 16; k++) + if (count + k < len) { + ch = isprint(buf[count + k]) ? + buf[count + k] : '.'; + snprintf(sbuf + strlen(sbuf), + sizeof(sbuf) - strlen(sbuf), "%c", ch); + } else + snprintf(sbuf + strlen(sbuf), + sizeof(sbuf) - strlen(sbuf), " "); + snprintf(sbuf + strlen(sbuf), + sizeof(sbuf) - strlen(sbuf), "\n"); + (void) write(outfd, sbuf, strlen(sbuf)); + } + ch = '\n'; + write(outfd, &ch, 1); +} + +/* + * Display usage and exit + */ +static void +Usage(void) +{ + fprintf(stderr, "usage: nghook [-adlnsS] path [hookname]\n"); + fprintf(stderr, " or: nghook -e [-n] [-m msg]* path hookname prog " + "[args...]\n"); + exit(EX_USAGE); +} + +/* + * Send the messages to the node + */ +static void +send_msgs(int cs, const char *path) +{ + u_int i; + + for (i = 0; i < msgs->sl_cur; i++) + if (NgSendAsciiMsg(cs, path, "%s", msgs->sl_str[i]) == -1) + err(EX_OSERR, "sending message '%s'", msgs->sl_str[i]); +} diff --git a/usr.sbin/nghook/nghook.8 b/usr.sbin/nghook/nghook.8 new file mode 100644 index 0000000..7d2c7fa --- /dev/null +++ b/usr.sbin/nghook/nghook.8 @@ -0,0 +1,145 @@ +.\" Copyright (c) 1996-1999 Whistle Communications, Inc. +.\" All rights reserved. +.\" +.\" Subject to the following obligations and disclaimer of warranty, use and +.\" redistribution of this software, in source or object code forms, with or +.\" without modifications are expressly permitted by Whistle Communications; +.\" provided, however, that: +.\" 1. Any and all reproductions of the source or object code must include the +.\" copyright notice above and the following disclaimer of warranties; and +.\" 2. No rights are granted, in any manner or form, to use Whistle +.\" Communications, Inc. trademarks, including the mark "WHISTLE +.\" COMMUNICATIONS" on advertising, endorsements, or otherwise except as +.\" such appears in the above copyright notice or in the software. +.\" +.\" THIS SOFTWARE IS BEING PROVIDED BY WHISTLE COMMUNICATIONS "AS IS", AND +.\" TO THE MAXIMUM EXTENT PERMITTED BY LAW, WHISTLE COMMUNICATIONS MAKES NO +.\" REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED, REGARDING THIS SOFTWARE, +.\" INCLUDING WITHOUT LIMITATION, ANY AND ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT. +.\" WHISTLE COMMUNICATIONS DOES NOT WARRANT, GUARANTEE, OR MAKE ANY +.\" REPRESENTATIONS REGARDING THE USE OF, OR THE RESULTS OF THE USE OF THIS +.\" SOFTWARE IN TERMS OF ITS CORRECTNESS, ACCURACY, RELIABILITY OR OTHERWISE. +.\" IN NO EVENT SHALL WHISTLE COMMUNICATIONS BE LIABLE FOR ANY DAMAGES +.\" RESULTING FROM OR ARISING OUT OF ANY USE OF THIS SOFTWARE, INCLUDING +.\" WITHOUT LIMITATION, ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, +.\" PUNITIVE, OR CONSEQUENTIAL DAMAGES, PROCUREMENT OF SUBSTITUTE GOODS OR +.\" SERVICES, LOSS OF USE, DATA OR PROFITS, HOWEVER CAUSED AND UNDER 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 WHISTLE COMMUNICATIONS IS ADVISED OF THE POSSIBILITY +.\" OF SUCH DAMAGE. +.\" +.\" $FreeBSD$ +.\" $Whistle: nghook.8,v 1.4 1999/01/20 03:19:45 archie Exp $ +.\" +.Dd October 24, 2003 +.Dt NGHOOK 8 +.Os +.Sh NAME +.Nm nghook +.Nd connect to a +.Xr netgraph 4 +node +.Sh SYNOPSIS +.Nm +.Op Fl adlnSs +.Op Fl m Ar msg +.Ar path +.Op Ar hookname +.Nm +.Fl e +.Op Fl n +.Op Fl m Ar msg +.Ar path +.Ar hookname +.Ar program +.Op Ar args ... +.Sh DESCRIPTION +The +.Nm +utility creates a +.Xr ng_socket 4 +socket type node and connects it to hook +.Ar hookname +of the node found at +.Ar path . +If +.Ar hookname +is omitted, +.Dq Li debug +is assumed. +.Pp +If the +.Fl e +option is given, the third argument is interpreted as the path to a program, +and this program is executed with the remaining arguments as its arguments. +Before executing, the program Netgraph messages (specified by the +.Fl m +option) are sent to the node. +The program is executed with its standard input (unless closed by +.Fl n ) +and output connected to the hook. +.Pp +If the +.Fl e +option is not given, all data written to standard input is sent +to the node, and all data received from the node is relayed +to standard output. +Messages specified with +.Fl m +are sent to the node before the loop is entered. +The +.Nm +utility exits when +.Dv EOF +is detected on standard input in this case. +.Pp +The options are as follows: +.Bl -tag -width indent +.It Fl a +Output each packet read in human-readable decoded +.Tn ASCII +form instead of raw binary. +.It Fl d +Increase the debugging verbosity level. +.It Fl e +Execute the program specified by the third argument. +.It Fl l +Loops all received data back to the hook in addition to writing it +to standard output. +.It Fl m Ar msg +Before executing the program (in +.Fl e +mode) send the given ASCII control message to the node. +This option may be given more than once. +.It Fl n +Do not attempt to read any data from standard input. +The +.Nm +utility will continue reading from the node until stopped by a signal. +.It Fl S +Use file descriptor 0 for output instead of the default 1. +.It Fl s +Use file descriptor 1 for input instead of the default 0. +.El +.Sh SEE ALSO +.Xr netgraph 3 , +.Xr netgraph 4 , +.Xr ngctl 8 +.Sh HISTORY +The +.Nm netgraph +system was designed and first implemented at Whistle Communications, Inc.\& +in a version of +.Fx 2.2 +customized for the Whistle InterJet. +.Sh AUTHORS +.An Archie Cobbs Aq archie@whistle.com +.Sh BUGS +Although all input is read in unbuffered mode, +there is no way to control the packetization of the input. +.Pp +If the node sends a response to a message (specified by +.Fl m ) , +this response is lost. |