msg.c revision 61880
153913Sarchie
253913Sarchie/*
353913Sarchie * msg.c
453913Sarchie *
553913Sarchie * Copyright (c) 1999 Whistle Communications, Inc.
653913Sarchie * All rights reserved.
753913Sarchie *
853913Sarchie * Subject to the following obligations and disclaimer of warranty, use and
953913Sarchie * redistribution of this software, in source or object code forms, with or
1053913Sarchie * without modifications are expressly permitted by Whistle Communications;
1153913Sarchie * provided, however, that:
1253913Sarchie * 1. Any and all reproductions of the source or object code must include the
1353913Sarchie *    copyright notice above and the following disclaimer of warranties; and
1453913Sarchie * 2. No rights are granted, in any manner or form, to use Whistle
1553913Sarchie *    Communications, Inc. trademarks, including the mark "WHISTLE
1653913Sarchie *    COMMUNICATIONS" on advertising, endorsements, or otherwise except as
1753913Sarchie *    such appears in the above copyright notice or in the software.
1853913Sarchie *
1953913Sarchie * THIS SOFTWARE IS BEING PROVIDED BY WHISTLE COMMUNICATIONS "AS IS", AND
2053913Sarchie * TO THE MAXIMUM EXTENT PERMITTED BY LAW, WHISTLE COMMUNICATIONS MAKES NO
2153913Sarchie * REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED, REGARDING THIS SOFTWARE,
2253913Sarchie * INCLUDING WITHOUT LIMITATION, ANY AND ALL IMPLIED WARRANTIES OF
2353913Sarchie * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT.
2453913Sarchie * WHISTLE COMMUNICATIONS DOES NOT WARRANT, GUARANTEE, OR MAKE ANY
2553913Sarchie * REPRESENTATIONS REGARDING THE USE OF, OR THE RESULTS OF THE USE OF THIS
2653913Sarchie * SOFTWARE IN TERMS OF ITS CORRECTNESS, ACCURACY, RELIABILITY OR OTHERWISE.
2753913Sarchie * IN NO EVENT SHALL WHISTLE COMMUNICATIONS BE LIABLE FOR ANY DAMAGES
2853913Sarchie * RESULTING FROM OR ARISING OUT OF ANY USE OF THIS SOFTWARE, INCLUDING
2953913Sarchie * WITHOUT LIMITATION, ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
3053913Sarchie * PUNITIVE, OR CONSEQUENTIAL DAMAGES, PROCUREMENT OF SUBSTITUTE GOODS OR
3153913Sarchie * SERVICES, LOSS OF USE, DATA OR PROFITS, HOWEVER CAUSED AND UNDER ANY
3253913Sarchie * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
3353913Sarchie * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
3453913Sarchie * THIS SOFTWARE, EVEN IF WHISTLE COMMUNICATIONS IS ADVISED OF THE POSSIBILITY
3553913Sarchie * OF SUCH DAMAGE.
3653913Sarchie *
3753913Sarchie * $Whistle: msg.c,v 1.2 1999/11/29 23:38:35 archie Exp $
3853913Sarchie * $FreeBSD: head/usr.sbin/ngctl/msg.c 61880 2000-06-20 18:51:38Z archie $
3953913Sarchie */
4053913Sarchie
4153913Sarchie#include "ngctl.h"
4253913Sarchie
4361880Sarchie#define BUF_SIZE	4096
4453913Sarchie
4553913Sarchiestatic int MsgCmd(int ac, char **av);
4653913Sarchie
4753913Sarchieconst struct ngcmd msg_cmd = {
4853913Sarchie	MsgCmd,
4953913Sarchie	"msg path command [args ... ]",
5053913Sarchie	"Send a netgraph control message to the node at \"path\"",
5153913Sarchie	"The msg command constructs a netgraph control message from the"
5253913Sarchie	" command name and ASCII arguments (if any) and sends that message"
5353913Sarchie	" to the node.  It does this by first asking the node to convert"
5458018Sarchie	" the ASCII message into binary format, and resending the result.",
5553913Sarchie	{ "cmd" }
5653913Sarchie};
5753913Sarchie
5853913Sarchiestatic int
5953913SarchieMsgCmd(int ac, char **av)
6053913Sarchie{
6153913Sarchie	char buf[BUF_SIZE];
6253913Sarchie	char *path, *cmdstr;
6353913Sarchie	int i;
6453913Sarchie
6553913Sarchie	/* Get arguments */
6653913Sarchie	if (ac < 3)
6753913Sarchie		return(CMDRTN_USAGE);
6853913Sarchie	path = av[1];
6953913Sarchie	cmdstr = av[2];
7053913Sarchie
7153913Sarchie	/* Put command and arguments back together as one string */
7253913Sarchie	for (*buf = '\0', i = 3; i < ac; i++) {
7353913Sarchie		snprintf(buf + strlen(buf),
7453913Sarchie		    sizeof(buf) - strlen(buf), " %s", av[i]);
7553913Sarchie	}
7653913Sarchie
7753913Sarchie	/* Send it */
7853913Sarchie	if (NgSendAsciiMsg(csock, path, "%s%s", cmdstr, buf) < 0) {
7953913Sarchie		warn("send msg");
8053913Sarchie		return(CMDRTN_ERROR);
8153913Sarchie	}
8253913Sarchie
8361880Sarchie	/* See if a synchronous reply awaits */
8461880Sarchie	{
8561880Sarchie		struct timeval tv;
8661880Sarchie		fd_set rfds;
8761880Sarchie
8861880Sarchie		FD_ZERO(&rfds);
8961880Sarchie		FD_SET(csock, &rfds);
9061880Sarchie		memset(&tv, 0, sizeof(tv));
9161880Sarchie		switch (select(csock + 1, &rfds, NULL, NULL, &tv)) {
9261880Sarchie		case -1:
9361880Sarchie			err(EX_OSERR, "select");
9461880Sarchie		case 0:
9561880Sarchie			break;
9661880Sarchie		default:
9761880Sarchie			MsgRead();
9861880Sarchie			break;
9961880Sarchie		}
10061880Sarchie	}
10161880Sarchie
10253913Sarchie	/* Done */
10353913Sarchie	return(CMDRTN_OK);
10453913Sarchie}
10553913Sarchie
10661880Sarchie/*
10761880Sarchie * Read and display the next incoming control message
10861880Sarchie */
10961880Sarchievoid
11061880SarchieMsgRead()
11161880Sarchie{
11261880Sarchie	u_char buf[2 * sizeof(struct ng_mesg) + BUF_SIZE];
11361880Sarchie	struct ng_mesg *const m = (struct ng_mesg *)buf;
11461880Sarchie	struct ng_mesg *const ascii = (struct ng_mesg *)m->data;
11561880Sarchie	char path[NG_PATHLEN+1];
11661880Sarchie
11761880Sarchie	/* Get incoming message (in binary form) */
11861880Sarchie	if (NgRecvMsg(csock, m, sizeof(buf), path) < 0) {
11961880Sarchie		warn("recv incoming message");
12061880Sarchie		return;
12161880Sarchie	}
12261880Sarchie
12361880Sarchie	/* Ask originating node to convert message to ASCII */
12461880Sarchie	if (NgSendMsg(csock, path, NGM_GENERIC_COOKIE,
12561880Sarchie	      NGM_BINARY2ASCII, m, sizeof(*m) + m->header.arglen) < 0
12661880Sarchie	    || NgRecvMsg(csock, m, sizeof(buf), NULL) < 0) {
12761880Sarchie		printf("Rec'd %s %d from \"%s\":\n",
12861880Sarchie		    (m->header.flags & NGF_RESP) != 0 ? "response" : "command",
12961880Sarchie		    m->header.cmd, path);
13061880Sarchie		if (m->header.arglen == 0)
13161880Sarchie			printf("No arguments\n");
13261880Sarchie		else
13361880Sarchie			DumpAscii(m->data, m->header.arglen);
13461880Sarchie		return;
13561880Sarchie	}
13661880Sarchie
13761880Sarchie	/* Display message in ASCII form */
13861880Sarchie	printf("Rec'd %s \"%s\" (%d) from \"%s\":\n",
13961880Sarchie	    (ascii->header.flags & NGF_RESP) != 0 ? "response" : "command",
14061880Sarchie	    ascii->header.cmdstr, ascii->header.cmd, path);
14161880Sarchie	if (*ascii->data != '\0')
14261880Sarchie		printf("Args:\t%s\n", ascii->data);
14361880Sarchie	else
14461880Sarchie		printf("No arguments\n");
14561880Sarchie}
14661880Sarchie
147