msg.c revision 122556
1234287Sdim
2234287Sdim/*
3234287Sdim * msg.c
4234287Sdim *
5234287Sdim * Copyright (c) 1999 Whistle Communications, Inc.
6234287Sdim * All rights reserved.
7234287Sdim *
8234287Sdim * Subject to the following obligations and disclaimer of warranty, use and
9234287Sdim * redistribution of this software, in source or object code forms, with or
10234287Sdim * without modifications are expressly permitted by Whistle Communications;
11243830Sdim * provided, however, that:
12234287Sdim * 1. Any and all reproductions of the source or object code must include the
13234287Sdim *    copyright notice above and the following disclaimer of warranties; and
14249423Sdim * 2. No rights are granted, in any manner or form, to use Whistle
15234287Sdim *    Communications, Inc. trademarks, including the mark "WHISTLE
16234287Sdim *    COMMUNICATIONS" on advertising, endorsements, or otherwise except as
17249423Sdim *    such appears in the above copyright notice or in the software.
18249423Sdim *
19249423Sdim * THIS SOFTWARE IS BEING PROVIDED BY WHISTLE COMMUNICATIONS "AS IS", AND
20249423Sdim * TO THE MAXIMUM EXTENT PERMITTED BY LAW, WHISTLE COMMUNICATIONS MAKES NO
21234287Sdim * REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED, REGARDING THIS SOFTWARE,
22234287Sdim * INCLUDING WITHOUT LIMITATION, ANY AND ALL IMPLIED WARRANTIES OF
23234287Sdim * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT.
24234287Sdim * WHISTLE COMMUNICATIONS DOES NOT WARRANT, GUARANTEE, OR MAKE ANY
25234287Sdim * REPRESENTATIONS REGARDING THE USE OF, OR THE RESULTS OF THE USE OF THIS
26234287Sdim * SOFTWARE IN TERMS OF ITS CORRECTNESS, ACCURACY, RELIABILITY OR OTHERWISE.
27234287Sdim * IN NO EVENT SHALL WHISTLE COMMUNICATIONS BE LIABLE FOR ANY DAMAGES
28234287Sdim * RESULTING FROM OR ARISING OUT OF ANY USE OF THIS SOFTWARE, INCLUDING
29234287Sdim * WITHOUT LIMITATION, ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
30234287Sdim * PUNITIVE, OR CONSEQUENTIAL DAMAGES, PROCUREMENT OF SUBSTITUTE GOODS OR
31234287Sdim * SERVICES, LOSS OF USE, DATA OR PROFITS, HOWEVER CAUSED AND UNDER ANY
32234287Sdim * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
33234287Sdim * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
34234287Sdim * THIS SOFTWARE, EVEN IF WHISTLE COMMUNICATIONS IS ADVISED OF THE POSSIBILITY
35234287Sdim * OF SUCH DAMAGE.
36234287Sdim *
37234287Sdim * $Whistle: msg.c,v 1.2 1999/11/29 23:38:35 archie Exp $
38234287Sdim * $FreeBSD: head/usr.sbin/ngctl/msg.c 122556 2003-11-12 13:04:44Z harti $
39234287Sdim */
40234287Sdim
41234287Sdim#include "ngctl.h"
42234287Sdim
43234287Sdim#define BUF_SIZE	4096
44234287Sdim
45234287Sdimstatic int MsgCmd(int ac, char **av);
46234287Sdim
47234287Sdimconst struct ngcmd msg_cmd = {
48234287Sdim	MsgCmd,
49234287Sdim	"msg path command [args ... ]",
50249423Sdim	"Send a netgraph control message to the node at \"path\"",
51249423Sdim	"The msg command constructs a netgraph control message from the"
52249423Sdim	" command name and ASCII arguments (if any) and sends that message"
53249423Sdim	" to the node.  It does this by first asking the node to convert"
54249423Sdim	" the ASCII message into binary format, and resending the result.",
55234287Sdim	{ "cmd" }
56234287Sdim};
57234287Sdim
58234287Sdimstatic int
59234287SdimMsgCmd(int ac, char **av)
60234287Sdim{
61234287Sdim	char buf[BUF_SIZE];
62234287Sdim	char *path, *cmdstr;
63234287Sdim	int i;
64234287Sdim
65234287Sdim	/* Get arguments */
66234287Sdim	if (ac < 3)
67234287Sdim		return(CMDRTN_USAGE);
68239462Sdim	path = av[1];
69243830Sdim	cmdstr = av[2];
70243830Sdim
71234287Sdim	/* Put command and arguments back together as one string */
72234287Sdim	for (*buf = '\0', i = 3; i < ac; i++) {
73234287Sdim		snprintf(buf + strlen(buf),
74234287Sdim		    sizeof(buf) - strlen(buf), " %s", av[i]);
75234287Sdim	}
76234287Sdim
77234287Sdim	/* Send it */
78234287Sdim	if (NgSendAsciiMsg(csock, path, "%s%s", cmdstr, buf) < 0) {
79234287Sdim		warn("send msg");
80234287Sdim		return(CMDRTN_ERROR);
81234287Sdim	}
82234287Sdim
83234287Sdim	/* See if a synchronous reply awaits */
84234287Sdim	{
85234287Sdim		struct timeval tv;
86234287Sdim		fd_set rfds;
87234287Sdim
88234287Sdim		FD_ZERO(&rfds);
89234287Sdim		FD_SET(csock, &rfds);
90234287Sdim		memset(&tv, 0, sizeof(tv));
91234287Sdim		switch (select(csock + 1, &rfds, NULL, NULL, &tv)) {
92234287Sdim		case -1:
93234287Sdim			err(EX_OSERR, "select");
94234287Sdim		case 0:
95234287Sdim			break;
96234287Sdim		default:
97234287Sdim			MsgRead();
98234287Sdim			break;
99234287Sdim		}
100234287Sdim	}
101234287Sdim
102234287Sdim	/* Done */
103234287Sdim	return(CMDRTN_OK);
104234287Sdim}
105234287Sdim
106234287Sdim/*
107234287Sdim * Read and display the next incoming control message
108234287Sdim */
109234287Sdimvoid
110234287SdimMsgRead()
111234287Sdim{
112234287Sdim	u_char buf[2 * sizeof(struct ng_mesg) + BUF_SIZE];
113234287Sdim	struct ng_mesg *const m = (struct ng_mesg *)buf;
114234287Sdim	struct ng_mesg *const ascii = (struct ng_mesg *)m->data;
115234287Sdim	char path[NG_PATHSIZ];
116234287Sdim
117234287Sdim	/* Get incoming message (in binary form) */
118234287Sdim	if (NgRecvMsg(csock, m, sizeof(buf), path) < 0) {
119234287Sdim		warn("recv incoming message");
120234287Sdim		return;
121234287Sdim	}
122234287Sdim
123234287Sdim	/* Ask originating node to convert message to ASCII */
124234287Sdim	if (NgSendMsg(csock, path, NGM_GENERIC_COOKIE,
125234287Sdim	      NGM_BINARY2ASCII, m, sizeof(*m) + m->header.arglen) < 0
126234287Sdim	    || NgRecvMsg(csock, m, sizeof(buf), NULL) < 0) {
127234287Sdim		printf("Rec'd %s %d from \"%s\":\n",
128239462Sdim		    (m->header.flags & NGF_RESP) != 0 ? "response" : "command",
129234287Sdim		    m->header.cmd, path);
130239462Sdim		if (m->header.arglen == 0)
131249423Sdim			printf("No arguments\n");
132234287Sdim		else
133249423Sdim			DumpAscii(m->data, m->header.arglen);
134249423Sdim		return;
135249423Sdim	}
136249423Sdim
137249423Sdim	/* Display message in ASCII form */
138234287Sdim	printf("Rec'd %s \"%s\" (%d) from \"%s\":\n",
139234287Sdim	    (ascii->header.flags & NGF_RESP) != 0 ? "response" : "command",
140234287Sdim	    ascii->header.cmdstr, ascii->header.cmd, path);
141249423Sdim	if (*ascii->data != '\0')
142249423Sdim		printf("Args:\t%s\n", ascii->data);
143234287Sdim	else
144239462Sdim		printf("No arguments\n");
145234287Sdim}
146234287Sdim
147234287Sdim