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