msg.c revision 216588
184059Swpaul
284059Swpaul/*
384059Swpaul * msg.c
484059Swpaul *
584059Swpaul * Copyright (c) 1999 Whistle Communications, Inc.
684059Swpaul * All rights reserved.
784059Swpaul *
884059Swpaul * Subject to the following obligations and disclaimer of warranty, use and
984059Swpaul * redistribution of this software, in source or object code forms, with or
1084059Swpaul * without modifications are expressly permitted by Whistle Communications;
1184059Swpaul * provided, however, that:
1284059Swpaul * 1. Any and all reproductions of the source or object code must include the
1384059Swpaul *    copyright notice above and the following disclaimer of warranties; and
1484059Swpaul * 2. No rights are granted, in any manner or form, to use Whistle
1584059Swpaul *    Communications, Inc. trademarks, including the mark "WHISTLE
1684059Swpaul *    COMMUNICATIONS" on advertising, endorsements, or otherwise except as
1784059Swpaul *    such appears in the above copyright notice or in the software.
1884059Swpaul *
1984059Swpaul * THIS SOFTWARE IS BEING PROVIDED BY WHISTLE COMMUNICATIONS "AS IS", AND
2084059Swpaul * TO THE MAXIMUM EXTENT PERMITTED BY LAW, WHISTLE COMMUNICATIONS MAKES NO
2184059Swpaul * REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED, REGARDING THIS SOFTWARE,
2284059Swpaul * INCLUDING WITHOUT LIMITATION, ANY AND ALL IMPLIED WARRANTIES OF
2384059Swpaul * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT.
2484059Swpaul * WHISTLE COMMUNICATIONS DOES NOT WARRANT, GUARANTEE, OR MAKE ANY
2584059Swpaul * REPRESENTATIONS REGARDING THE USE OF, OR THE RESULTS OF THE USE OF THIS
2684059Swpaul * SOFTWARE IN TERMS OF ITS CORRECTNESS, ACCURACY, RELIABILITY OR OTHERWISE.
2784059Swpaul * IN NO EVENT SHALL WHISTLE COMMUNICATIONS BE LIABLE FOR ANY DAMAGES
2884059Swpaul * RESULTING FROM OR ARISING OUT OF ANY USE OF THIS SOFTWARE, INCLUDING
2984059Swpaul * WITHOUT LIMITATION, ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
3084059Swpaul * PUNITIVE, OR CONSEQUENTIAL DAMAGES, PROCUREMENT OF SUBSTITUTE GOODS OR
3184059Swpaul * SERVICES, LOSS OF USE, DATA OR PROFITS, HOWEVER CAUSED AND UNDER ANY
3284059Swpaul * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
3384059Swpaul * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
3484059Swpaul * THIS SOFTWARE, EVEN IF WHISTLE COMMUNICATIONS IS ADVISED OF THE POSSIBILITY
3584059Swpaul * OF SUCH DAMAGE.
3684059Swpaul *
3784059Swpaul * $Whistle: msg.c,v 1.2 1999/11/29 23:38:35 archie Exp $
3884059Swpaul */
3984059Swpaul
4084059Swpaul#include <sys/cdefs.h>
4184059Swpaul__FBSDID("$FreeBSD: head/usr.sbin/ngctl/msg.c 216588 2010-12-20 09:36:54Z charnier $");
4284059Swpaul
4384059Swpaul#include <err.h>
4484059Swpaul#include <netgraph.h>
4584059Swpaul#include <stdio.h>
4684059Swpaul#include <stdlib.h>
4784059Swpaul#include <string.h>
4884059Swpaul#include <sysexits.h>
4984059Swpaul#include <unistd.h>
5084059Swpaul
5184059Swpaul#include "ngctl.h"
5284059Swpaul
5384059Swpaulstatic int MsgCmd(int ac, char **av);
5484059Swpaul
5584059Swpaulconst struct ngcmd msg_cmd = {
5684059Swpaul	MsgCmd,
5784059Swpaul	"msg path command [args ... ]",
5884059Swpaul	"Send a netgraph control message to the node at \"path\"",
5984059Swpaul	"The msg command constructs a netgraph control message from the"
6092934Swpaul	" command name and ASCII arguments (if any) and sends that message"
6184059Swpaul	" to the node.  It does this by first asking the node to convert"
6284059Swpaul	" the ASCII message into binary format, and resending the result.",
6384059Swpaul	{ "cmd" }
6484059Swpaul};
6584059Swpaul
6684059Swpaulstatic int
6784059SwpaulMsgCmd(int ac, char **av)
6884059Swpaul{
6984059Swpaul	char *buf;
7084059Swpaul	char *path, *cmdstr;
7184059Swpaul	int i, len;
7284059Swpaul
7384059Swpaul	/* Get arguments */
7484059Swpaul	if (ac < 3)
7584059Swpaul		return (CMDRTN_USAGE);
7684059Swpaul	path = av[1];
7784059Swpaul	cmdstr = av[2];
7884059Swpaul
7984059Swpaul	/* Put command and arguments back together as one string */
8084059Swpaul	for (len = 1, i = 3; i < ac; i++)
8184059Swpaul		len += strlen(av[i]) + 1;
8284059Swpaul	if ((buf = malloc(len)) == NULL) {
8384059Swpaul		warn("malloc");
8484059Swpaul		return (CMDRTN_ERROR);
8584059Swpaul	}
8684059Swpaul	for (*buf = '\0', i = 3; i < ac; i++) {
8784059Swpaul		snprintf(buf + strlen(buf),
8884059Swpaul		    len - strlen(buf), " %s", av[i]);
8984059Swpaul	}
9084059Swpaul
9184059Swpaul	/* Send it */
9284059Swpaul	if (NgSendAsciiMsg(csock, path, "%s%s", cmdstr, buf) < 0) {
9384059Swpaul		free(buf);
9484059Swpaul		warn("send msg");
9584059Swpaul		return (CMDRTN_ERROR);
9684059Swpaul	}
9784059Swpaul	free(buf);
9884059Swpaul
9984059Swpaul	/* See if a synchronous reply awaits */
10084059Swpaul	{
10184059Swpaul		struct timeval tv;
10284059Swpaul		fd_set rfds;
10384059Swpaul
10484059Swpaul		FD_ZERO(&rfds);
10584059Swpaul		FD_SET(csock, &rfds);
10684059Swpaul		memset(&tv, 0, sizeof(tv));
10784059Swpaul		switch (select(csock + 1, &rfds, NULL, NULL, &tv)) {
10884059Swpaul		case -1:
10984059Swpaul			err(EX_OSERR, "select");
11084059Swpaul		case 0:
11184059Swpaul			break;
11284059Swpaul		default:
11384059Swpaul			MsgRead();
11484059Swpaul			break;
11584059Swpaul		}
11699417Sjdp	}
11784059Swpaul
11884059Swpaul	/* Done */
11984059Swpaul	return (CMDRTN_OK);
12084059Swpaul}
12184059Swpaul
12284059Swpaul/*
12384059Swpaul * Read and display the next incoming control message
12484059Swpaul */
12584059Swpaulvoid
12684059SwpaulMsgRead(void)
12784059Swpaul{
12884059Swpaul	struct ng_mesg *m, *m2;
12984059Swpaul	struct ng_mesg *ascii;
13084059Swpaul	char path[NG_PATHSIZ];
13184059Swpaul
13284059Swpaul	/* Get incoming message (in binary form) */
13384059Swpaul	if (NgAllocRecvMsg(csock, &m, path) < 0) {
13484059Swpaul		warn("recv incoming message");
13584059Swpaul		return;
13684059Swpaul	}
13784059Swpaul
13884059Swpaul	/* Ask originating node to convert message to ASCII */
13984059Swpaul	if (NgSendMsg(csock, path, NGM_GENERIC_COOKIE,
14084059Swpaul	      NGM_BINARY2ASCII, m, sizeof(*m) + m->header.arglen) < 0
14184059Swpaul	    || NgAllocRecvMsg(csock, &m2, NULL) < 0) {
14284059Swpaul		printf("Rec'd %s %d from \"%s\":\n",
14384059Swpaul		    (m->header.flags & NGF_RESP) != 0 ? "response" : "command",
144103103Sjdp		    m->header.cmd, path);
145103103Sjdp		if (m->header.arglen == 0)
14684059Swpaul			printf("No arguments\n");
14784059Swpaul		else
14889835Sjdp			DumpAscii((const u_char *)m->data, m->header.arglen);
14989835Sjdp		free(m);
150100695Sjdp		return;
151100695Sjdp	}
15284059Swpaul
15384059Swpaul	/* Display message in ASCII form */
15484059Swpaul	free(m);
15592739Salfred	ascii = (struct ng_mesg *)m2->data;
15692739Salfred	printf("Rec'd %s \"%s\" (%d) from \"%s\":\n",
15792739Salfred	    (ascii->header.flags & NGF_RESP) != 0 ? "response" : "command",
15884059Swpaul	    ascii->header.cmdstr, ascii->header.cmd, path);
15992739Salfred	if (*ascii->data != '\0')
16092739Salfred		printf("Args:\t%s\n", ascii->data);
16192739Salfred	else
16284059Swpaul		printf("No arguments\n");
16392739Salfred	free(m2);
16492739Salfred}
16592739Salfred
16692739Salfred