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