main.c revision 119020
152419Sjulian/* 252419Sjulian * main.c 352419Sjulian * 452419Sjulian * Copyright (c) 1996-1999 Whistle Communications, Inc. 552419Sjulian * All rights reserved. 652419Sjulian * 752419Sjulian * Subject to the following obligations and disclaimer of warranty, use and 852419Sjulian * redistribution of this software, in source or object code forms, with or 952419Sjulian * without modifications are expressly permitted by Whistle Communications; 1052419Sjulian * provided, however, that: 1152419Sjulian * 1. Any and all reproductions of the source or object code must include the 1252419Sjulian * copyright notice above and the following disclaimer of warranties; and 1352419Sjulian * 2. No rights are granted, in any manner or form, to use Whistle 1452419Sjulian * Communications, Inc. trademarks, including the mark "WHISTLE 1552419Sjulian * COMMUNICATIONS" on advertising, endorsements, or otherwise except as 1652419Sjulian * such appears in the above copyright notice or in the software. 1752419Sjulian * 1852419Sjulian * THIS SOFTWARE IS BEING PROVIDED BY WHISTLE COMMUNICATIONS "AS IS", AND 1952419Sjulian * TO THE MAXIMUM EXTENT PERMITTED BY LAW, WHISTLE COMMUNICATIONS MAKES NO 2052419Sjulian * REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED, REGARDING THIS SOFTWARE, 2152419Sjulian * INCLUDING WITHOUT LIMITATION, ANY AND ALL IMPLIED WARRANTIES OF 2252419Sjulian * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT. 2352419Sjulian * WHISTLE COMMUNICATIONS DOES NOT WARRANT, GUARANTEE, OR MAKE ANY 2452419Sjulian * REPRESENTATIONS REGARDING THE USE OF, OR THE RESULTS OF THE USE OF THIS 2552419Sjulian * SOFTWARE IN TERMS OF ITS CORRECTNESS, ACCURACY, RELIABILITY OR OTHERWISE. 2652419Sjulian * IN NO EVENT SHALL WHISTLE COMMUNICATIONS BE LIABLE FOR ANY DAMAGES 2752419Sjulian * RESULTING FROM OR ARISING OUT OF ANY USE OF THIS SOFTWARE, INCLUDING 2852419Sjulian * WITHOUT LIMITATION, ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, 2952419Sjulian * PUNITIVE, OR CONSEQUENTIAL DAMAGES, PROCUREMENT OF SUBSTITUTE GOODS OR 3052419Sjulian * SERVICES, LOSS OF USE, DATA OR PROFITS, HOWEVER CAUSED AND UNDER ANY 3152419Sjulian * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 3252419Sjulian * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 3352419Sjulian * THIS SOFTWARE, EVEN IF WHISTLE COMMUNICATIONS IS ADVISED OF THE POSSIBILITY 3452419Sjulian * OF SUCH DAMAGE. 3552419Sjulian * 3652419Sjulian * $Whistle: main.c,v 1.9 1999/01/20 00:26:26 archie Exp $ 3752419Sjulian */ 3852419Sjulian 39119020Scharnier#include <sys/cdefs.h> 40119020Scharnier__FBSDID("$FreeBSD: head/usr.sbin/nghook/main.c 119020 2003-08-17 09:06:08Z charnier $"); 41119020Scharnier 4252419Sjulian#include <stdio.h> 4352419Sjulian#include <stdlib.h> 4452419Sjulian#include <string.h> 4552419Sjulian#include <ctype.h> 4652419Sjulian#include <unistd.h> 4752419Sjulian#include <sysexits.h> 4852419Sjulian#include <errno.h> 4952419Sjulian#include <err.h> 5052419Sjulian 5152419Sjulian#include <sys/types.h> 5252419Sjulian#include <sys/socket.h> 5352419Sjulian#include <sys/select.h> 5452419Sjulian 5552450Sdillon#include <netgraph.h> 5652419Sjulian 5752419Sjulian#define DEFAULT_HOOKNAME "debug" 5852419Sjulian#define NG_SOCK_HOOK_NAME "hook" 5952419Sjulian 6052419Sjulian#define BUF_SIZE (64 * 1024) 6152419Sjulian 6252419Sjulianstatic void WriteAscii(u_char * buf, int len); 6352419Sjulianstatic void Usage(void); 6452419Sjulian 65118858Shartistatic int outfd = STDOUT_FILENO; 66118858Shartistatic int infd = STDIN_FILENO; 67118858Sharti 6852419Sjulian/* 6952419Sjulian * main() 7052419Sjulian */ 7152419Sjulianint 7252419Sjulianmain(int ac, char *av[]) 7352419Sjulian{ 7452419Sjulian struct ngm_connect ngc; 75118860Sharti const char *path = NULL; 76118860Sharti const char *hook = DEFAULT_HOOKNAME; 7752419Sjulian int csock, dsock; 7852419Sjulian int asciiFlag = 0; 7963436Sphk int loopFlag = 0; 8063931Sarchie int noInput = 0; 8152419Sjulian int ch; 8252419Sjulian 8352419Sjulian /* Parse flags */ 84119020Scharnier while ((ch = getopt(ac, av, "adlnsS")) != -1) { 8552419Sjulian switch (ch) { 8663436Sphk case 'a': 8763436Sphk asciiFlag = 1; 8863436Sphk break; 8952419Sjulian case 'd': 9052419Sjulian NgSetDebug(NgSetDebug(-1) + 1); 9152419Sjulian break; 9263436Sphk case 'l': 9363436Sphk loopFlag = 1; 9452419Sjulian break; 9563931Sarchie case 'n': 9663931Sarchie noInput = 1; 9763931Sarchie break; 98118858Sharti case 's': 99118858Sharti outfd = STDIN_FILENO; 100118858Sharti break; 101118858Sharti case 'S': 102118858Sharti infd = STDOUT_FILENO; 103118858Sharti break; 10452419Sjulian case '?': 10552419Sjulian default: 10652419Sjulian Usage(); 10752419Sjulian } 10852419Sjulian } 10952419Sjulian ac -= optind; 11052419Sjulian av += optind; 11152419Sjulian 11252419Sjulian /* Get params */ 11352419Sjulian switch (ac) { 11452419Sjulian case 2: 11552419Sjulian hook = av[1]; 11652419Sjulian /* FALLTHROUGH */ 11752419Sjulian case 1: 11852419Sjulian path = av[0]; 11952419Sjulian break; 12052419Sjulian default: 12152419Sjulian Usage(); 12252419Sjulian } 12352419Sjulian 12452419Sjulian /* Get sockets */ 12552419Sjulian if (NgMkSockNode(NULL, &csock, &dsock) < 0) 12652419Sjulian errx(EX_OSERR, "can't get sockets"); 12752419Sjulian 12852419Sjulian /* Connect socket node to specified node */ 12952419Sjulian snprintf(ngc.path, sizeof(ngc.path), "%s", path); 13052419Sjulian snprintf(ngc.ourhook, sizeof(ngc.ourhook), NG_SOCK_HOOK_NAME); 13152419Sjulian snprintf(ngc.peerhook, sizeof(ngc.peerhook), "%s", hook); 13252419Sjulian 13352419Sjulian if (NgSendMsg(csock, ".", 13452419Sjulian NGM_GENERIC_COOKIE, NGM_CONNECT, &ngc, sizeof(ngc)) < 0) 13552419Sjulian errx(EX_OSERR, "can't connect to node"); 13652419Sjulian 13763931Sarchie /* Close standard input if not reading from it */ 13863931Sarchie if (noInput) 13963931Sarchie fclose(stdin); 14063931Sarchie 14152419Sjulian /* Relay data */ 14252419Sjulian while (1) { 14352419Sjulian fd_set rfds; 14452419Sjulian 14552419Sjulian /* Setup bits */ 14652419Sjulian FD_ZERO(&rfds); 14763931Sarchie if (!noInput) 148118858Sharti FD_SET(infd, &rfds); 14952419Sjulian FD_SET(dsock, &rfds); 15052419Sjulian 15152419Sjulian /* Wait for something to happen */ 15252419Sjulian if (select(FD_SETSIZE, &rfds, NULL, NULL, NULL) < 0) 15352419Sjulian err(EX_OSERR, "select"); 15452419Sjulian 15552419Sjulian /* Check data from socket */ 15652419Sjulian if (FD_ISSET(dsock, &rfds)) { 15752419Sjulian char buf[BUF_SIZE]; 15852419Sjulian int rl, wl; 15952419Sjulian 16052419Sjulian /* Read packet from socket */ 16152419Sjulian if ((rl = NgRecvData(dsock, 16252419Sjulian buf, sizeof(buf), NULL)) < 0) 16352419Sjulian err(EX_OSERR, "read(hook)"); 16452419Sjulian if (rl == 0) 16552419Sjulian errx(EX_OSERR, "read EOF from hook?!"); 16652419Sjulian 16752419Sjulian /* Write packet to stdout */ 16852419Sjulian if (asciiFlag) 16952419Sjulian WriteAscii((u_char *) buf, rl); 170118858Sharti else if ((wl = write(outfd, buf, rl)) != rl) { 17152419Sjulian if (wl < 0) { 17252419Sjulian err(EX_OSERR, "write(stdout)"); 17352419Sjulian } else { 17452419Sjulian errx(EX_OSERR, 17552419Sjulian "stdout: read %d, wrote %d", 17652419Sjulian rl, wl); 17752419Sjulian } 17852419Sjulian } 17963436Sphk /* Loopback */ 18063436Sphk if (loopFlag) { 18163436Sphk if (NgSendData(dsock, NG_SOCK_HOOK_NAME, buf, rl) < 0) 18263436Sphk err(EX_OSERR, "write(hook)"); 18363436Sphk } 18452419Sjulian } 18552419Sjulian 18652419Sjulian /* Check data from stdin */ 187118858Sharti if (FD_ISSET(infd, &rfds)) { 18852419Sjulian char buf[BUF_SIZE]; 18952419Sjulian int rl; 19052419Sjulian 19152419Sjulian /* Read packet from stdin */ 192118858Sharti if ((rl = read(infd, buf, sizeof(buf))) < 0) 19352419Sjulian err(EX_OSERR, "read(stdin)"); 19452419Sjulian if (rl == 0) 19552419Sjulian errx(EX_OSERR, "EOF(stdin)"); 19652419Sjulian 19752419Sjulian /* Write packet to socket */ 19852419Sjulian if (NgSendData(dsock, NG_SOCK_HOOK_NAME, buf, rl) < 0) 19952419Sjulian err(EX_OSERR, "write(hook)"); 20052419Sjulian } 20152419Sjulian } 20252419Sjulian} 20352419Sjulian 20452419Sjulian/* 20552419Sjulian * Dump data in hex and ASCII form 20652419Sjulian */ 20752419Sjulianstatic void 20852419SjulianWriteAscii(u_char *buf, int len) 20952419Sjulian{ 21052419Sjulian char ch, sbuf[100]; 21152419Sjulian int k, count; 21252419Sjulian 21352419Sjulian for (count = 0; count < len; count += 16) { 21452419Sjulian snprintf(sbuf, sizeof(sbuf), "%04x: ", count); 21552419Sjulian for (k = 0; k < 16; k++) 21652419Sjulian if (count + k < len) 21752419Sjulian snprintf(sbuf + strlen(sbuf), 21852419Sjulian sizeof(sbuf) - strlen(sbuf), 21952419Sjulian "%02x ", buf[count + k]); 22052419Sjulian else 22152419Sjulian snprintf(sbuf + strlen(sbuf), 22252419Sjulian sizeof(sbuf) - strlen(sbuf), " "); 22352419Sjulian snprintf(sbuf + strlen(sbuf), sizeof(sbuf) - strlen(sbuf), " "); 22452419Sjulian for (k = 0; k < 16; k++) 22552419Sjulian if (count + k < len) { 22652419Sjulian ch = isprint(buf[count + k]) ? 22752419Sjulian buf[count + k] : '.'; 22852419Sjulian snprintf(sbuf + strlen(sbuf), 22952419Sjulian sizeof(sbuf) - strlen(sbuf), "%c", ch); 23052419Sjulian } else 23152419Sjulian snprintf(sbuf + strlen(sbuf), 23253908Sarchie sizeof(sbuf) - strlen(sbuf), " "); 23352419Sjulian snprintf(sbuf + strlen(sbuf), 23452419Sjulian sizeof(sbuf) - strlen(sbuf), "\n"); 235118858Sharti (void) write(outfd, sbuf, strlen(sbuf)); 23652419Sjulian } 23752419Sjulian ch = '\n'; 238118858Sharti write(outfd, &ch, 1); 23952419Sjulian} 24052419Sjulian 24152419Sjulian/* 24252419Sjulian * Display usage and exit 24352419Sjulian */ 24452419Sjulianstatic void 24552419SjulianUsage(void) 24652419Sjulian{ 247119020Scharnier fprintf(stderr, "usage: nghook [-adlnsS] path [hookname]\n"); 248119020Scharnier exit(EX_USAGE); 24952419Sjulian} 250