189674Sarchie 289674Sarchie/* 389674Sarchie * write.c 489674Sarchie * 589674Sarchie * Copyright (c) 2002 Archie L. Cobbs 689674Sarchie * All rights reserved. 789674Sarchie * 889674Sarchie * Subject to the following obligations and disclaimer of warranty, use and 989674Sarchie * redistribution of this software, in source or object code forms, with or 1089674Sarchie * without modifications are expressly permitted by Archie L. Cobbs; 1189674Sarchie * provided, however, that: 1289674Sarchie * 1. Any and all reproductions of the source or object code must include the 1389674Sarchie * copyright notice above and the following disclaimer of warranties 1489674Sarchie * 1589674Sarchie * THIS SOFTWARE IS BEING PROVIDED BY ARCHIE L. COBBS AS IS", AND TO 1689674Sarchie * THE MAXIMUM EXTENT PERMITTED BY LAW, ARCHIE L. COBBS MAKES NO 1789674Sarchie * REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED, REGARDING THIS SOFTWARE, 1889674Sarchie * INCLUDING WITHOUT LIMITATION, ANY AND ALL IMPLIED WARRANTIES OF 1989674Sarchie * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT. 2089674Sarchie * ARCHIE L. COBBS DOES NOT WARRANT, GUARANTEE, OR MAKE ANY 2189674Sarchie * REPRESENTATIONS REGARDING THE USE OF, OR THE RESULTS OF THE USE OF THIS 2289674Sarchie * SOFTWARE IN TERMS OF ITS CORRECTNESS, ACCURACY, RELIABILITY OR OTHERWISE. 2389674Sarchie * IN NO EVENT SHALL ARCHIE L. COBBS BE LIABLE FOR ANY DAMAGES 2489674Sarchie * RESULTING FROM OR ARISING OUT OF ANY USE OF THIS SOFTWARE, INCLUDING 2589674Sarchie * WITHOUT LIMITATION, ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, 2689674Sarchie * PUNITIVE, OR CONSEQUENTIAL DAMAGES, PROCUREMENT OF SUBSTITUTE GOODS OR 2789674Sarchie * SERVICES, LOSS OF USE, DATA OR PROFITS, HOWEVER CAUSED AND UNDER ANY 2889674Sarchie * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 2989674Sarchie * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 3089674Sarchie * THIS SOFTWARE, EVEN IF ARCHIE L. COBBS IS ADVISED OF THE POSSIBILITY 3189674Sarchie * OF SUCH DAMAGE. 3289674Sarchie * 3389674Sarchie * $FreeBSD$ 3489674Sarchie */ 3589674Sarchie 36158882Sglebius#include <sys/types.h> 37158882Sglebius#include <sys/socket.h> 38158882Sglebius 39158882Sglebius#include <err.h> 40158882Sglebius#include <stdio.h> 41158882Sglebius#include <string.h> 42158882Sglebius#include <unistd.h> 43158882Sglebius 44158882Sglebius#include <netgraph/ng_socket.h> 45158882Sglebius 4689674Sarchie#include "ngctl.h" 4789674Sarchie 4889674Sarchie#define BUF_SIZE 8192 4989674Sarchie 5089674Sarchiestatic int WriteCmd(int ac, char **av); 5189674Sarchie 5289674Sarchieconst struct ngcmd write_cmd = { 5389674Sarchie WriteCmd, 5489674Sarchie "write hook < -f file | byte ... >", 5589674Sarchie "Send a data packet down the hook named by \"hook\".", 5689674Sarchie "The data may be contained in a file, or may be described directly" 5789674Sarchie " on the command line by supplying a sequence of bytes.", 5889674Sarchie { "w" } 5989674Sarchie}; 6089674Sarchie 6189674Sarchiestatic int 6289674SarchieWriteCmd(int ac, char **av) 6389674Sarchie{ 6489674Sarchie u_int32_t sagbuf[64]; 6589674Sarchie struct sockaddr_ng *sag = (struct sockaddr_ng *)sagbuf; 6689674Sarchie u_char buf[BUF_SIZE]; 6789674Sarchie const char *hook; 6889674Sarchie FILE *fp; 6989674Sarchie u_int len; 7089674Sarchie int byte; 7189674Sarchie int i; 7289674Sarchie 7389674Sarchie /* Get arguments */ 7489674Sarchie if (ac < 3) 75160002Sglebius return (CMDRTN_USAGE); 7689674Sarchie hook = av[1]; 7789674Sarchie 7889674Sarchie /* Get data */ 7989674Sarchie if (strcmp(av[2], "-f") == 0) { 8089674Sarchie if (ac != 4) 81160002Sglebius return (CMDRTN_USAGE); 8289674Sarchie if ((fp = fopen(av[3], "r")) == NULL) { 8389674Sarchie warn("can't read file \"%s\"", av[3]); 84160002Sglebius return (CMDRTN_ERROR); 8589674Sarchie } 8689674Sarchie if ((len = fread(buf, 1, sizeof(buf), fp)) == 0) { 8789674Sarchie if (ferror(fp)) 8889674Sarchie warn("can't read file \"%s\"", av[3]); 8989674Sarchie else 9089674Sarchie warnx("file \"%s\" is empty", av[3]); 9189674Sarchie fclose(fp); 92160002Sglebius return (CMDRTN_ERROR); 9389674Sarchie } 9489674Sarchie fclose(fp); 9589674Sarchie } else { 9689674Sarchie for (i = 2, len = 0; i < ac && len < sizeof(buf); i++, len++) { 9789674Sarchie if (sscanf(av[i], "%i", &byte) != 1 9889674Sarchie || (byte < -128 || byte > 255)) { 9989674Sarchie warnx("invalid byte \"%s\"", av[i]); 100160002Sglebius return (CMDRTN_ERROR); 10189674Sarchie } 10289674Sarchie buf[len] = (u_char)byte; 10389674Sarchie } 10489674Sarchie if (len == 0) 105160002Sglebius return (CMDRTN_USAGE); 10689674Sarchie } 10789674Sarchie 10889674Sarchie /* Send data */ 10989674Sarchie sag->sg_len = 3 + strlen(hook); 11089674Sarchie sag->sg_family = AF_NETGRAPH; 11189674Sarchie strlcpy(sag->sg_data, hook, sizeof(sagbuf) - 2); 11289674Sarchie if (sendto(dsock, buf, len, 11389674Sarchie 0, (struct sockaddr *)sag, sag->sg_len) == -1) { 11489674Sarchie warn("writing to hook \"%s\"", hook); 115160002Sglebius return (CMDRTN_ERROR); 11689674Sarchie } 11789674Sarchie 11889674Sarchie /* Done */ 119160002Sglebius return (CMDRTN_OK); 12089674Sarchie} 12189674Sarchie 122