summaryrefslogtreecommitdiffstats
path: root/lib/libnetgraph
diff options
context:
space:
mode:
Diffstat (limited to 'lib/libnetgraph')
-rw-r--r--lib/libnetgraph/Makefile3
-rw-r--r--lib/libnetgraph/debug.c377
-rw-r--r--lib/libnetgraph/internal.h4
-rw-r--r--lib/libnetgraph/msg.c109
-rw-r--r--lib/libnetgraph/netgraph.368
-rw-r--r--lib/libnetgraph/netgraph.h2
6 files changed, 309 insertions, 254 deletions
diff --git a/lib/libnetgraph/Makefile b/lib/libnetgraph/Makefile
index 569a1f7..342b2e5 100644
--- a/lib/libnetgraph/Makefile
+++ b/lib/libnetgraph/Makefile
@@ -9,8 +9,7 @@ SHLIB_MAJOR= 1
SRCS= sock.c msg.c debug.c
-CFLAGS+= -g -Wall -O2 -Werror
-CFLAGS+= -I/usr/src.freefall/sys
+CFLAGS+= -g -Wall
beforeinstall:
${INSTALL} -C -o ${BINOWN} -g ${BINGRP} -m 444 ${.CURDIR}/netgraph.h \
diff --git a/lib/libnetgraph/debug.c b/lib/libnetgraph/debug.c
index bf57da6..cd7f7cb 100644
--- a/lib/libnetgraph/debug.c
+++ b/lib/libnetgraph/debug.c
@@ -41,24 +41,45 @@
*/
#include <sys/types.h>
+
#include <stdarg.h>
+
+#include <netinet/in.h>
+#include <net/ethernet.h>
+
#include <netgraph/ng_message.h>
#include <netgraph/ng_socket.h>
#include "netgraph.h"
#include "internal.h"
-#include <netgraph/ng_socket.h>
-#include <netgraph/ng_message.h>
-#include <netgraph/ng_iface.h>
-#include <netgraph/ng_rfc1490.h>
-#include <netgraph/ng_cisco.h>
+#include <netgraph/ng_UI.h>
#include <netgraph/ng_async.h>
-#include <netgraph/ng_ppp.h>
+#include <netgraph/ng_cisco.h>
+#include <netgraph/ng_echo.h>
+#include <netgraph/ng_ether.h>
#include <netgraph/ng_frame_relay.h>
+#include <netgraph/ng_hole.h>
+#include <netgraph/ng_iface.h>
+#include <netgraph/ng_ksocket.h>
#include <netgraph/ng_lmi.h>
+#include <netgraph/ng_ppp.h>
+#include <netgraph/ng_pppoe.h>
+#include <netgraph/ng_rfc1490.h>
+#include <netgraph/ng_socket.h>
+#include <netgraph/ng_tee.h>
#include <netgraph/ng_tty.h>
-#include <netgraph/ng_tty.h>
+#include <netgraph/ng_vjc.h>
+#ifdef WHISTLE
+#include <machine/../isa/df_def.h>
+#include <machine/../isa/if_wfra.h>
+#include <machine/../isa/ipac.h>
+#include <netgraph/ng_df.h>
+#include <netgraph/ng_ipac.h>
+#include <netgraph/ng_mppc.h>
+#include <netgraph/ng_pptpgre.h>
+#include <netgraph/ng_tn.h>
+#endif
/* Global debug level */
int _gNgDebugLevel = 0;
@@ -69,8 +90,45 @@ void (*_NgLogx) (const char *fmt,...) = warnx;
/* Internal functions */
static const char *NgCookie(int cookie);
-static const char *NgCmd(int cookie, int cmd);
-static void NgArgs(int cookie, int cmd, int resp, void *args, int arglen);
+
+/* Known typecookie list */
+struct ng_cookie {
+ int cookie;
+ const char *type;
+};
+
+#define COOKIE(c) { NGM_ ## c ## _COOKIE, #c }
+
+/* List of known cookies */
+static const struct ng_cookie cookies[] = {
+ COOKIE(UI),
+ COOKIE(ASYNC),
+ COOKIE(CISCO),
+ COOKIE(ECHO),
+ COOKIE(ETHER),
+ COOKIE(FRAMERELAY),
+ COOKIE(GENERIC),
+ COOKIE(HOLE),
+ COOKIE(IFACE),
+ COOKIE(KSOCKET),
+ COOKIE(LMI),
+ COOKIE(PPP),
+ COOKIE(PPPOE),
+ COOKIE(RFC1490),
+ COOKIE(SOCKET),
+ COOKIE(TEE),
+ COOKIE(TTY),
+ COOKIE(VJC),
+#ifdef WHISTLE
+ COOKIE(DF),
+ COOKIE(IPAC),
+ COOKIE(MPPC),
+ COOKIE(PPTPGRE),
+ COOKIE(TN),
+ COOKIE(WFRA),
+#endif
+ { 0, NULL }
+};
/*
* Set debug level, ie, verbosity, if "level" is non-negative.
@@ -102,27 +160,82 @@ NgSetErrLog(void (*log) (const char *fmt,...),
* Display a netgraph sockaddr
*/
void
-_NgDebugSockaddr(struct sockaddr_ng *sg)
+_NgDebugSockaddr(const struct sockaddr_ng *sg)
{
NGLOGX("SOCKADDR: { fam=%d len=%d addr=\"%s\" }",
sg->sg_family, sg->sg_len, sg->sg_data);
}
+#define ARGS_BUFSIZE 1024
+
/*
* Display a negraph message
*/
void
-_NgDebugMsg(struct ng_mesg * msg)
+_NgDebugMsg(const struct ng_mesg *msg, const char *path)
{
+ u_char buf[2 * sizeof(struct ng_mesg) + ARGS_BUFSIZE];
+ struct ng_mesg *const req = (struct ng_mesg *)buf;
+ struct ng_mesg *const bin = (struct ng_mesg *)req->data;
+ int arglen, debugSave, csock = -1;
+
+ /* Lower debugging to avoid infinite recursion */
+ debugSave = _gNgDebugLevel;
+ _gNgDebugLevel -= 4;
+
+ /* Display header stuff */
NGLOGX("NG_MESG :");
NGLOGX(" vers %d", msg->header.version);
NGLOGX(" arglen %d", msg->header.arglen);
NGLOGX(" flags %ld", msg->header.flags);
- NGLOGX(" token %lu", (u_long) msg->header.token);
- NGLOGX(" cookie %s", NgCookie(msg->header.typecookie));
- NGLOGX(" cmd %s", NgCmd(msg->header.typecookie, msg->header.cmd));
- NgArgs(msg->header.typecookie, msg->header.cmd,
- (msg->header.flags & NGF_RESP), msg->data, msg->header.arglen);
+ NGLOGX(" token %lu", (u_long)msg->header.token);
+ NGLOGX(" cookie %s (%d)",
+ NgCookie(msg->header.typecookie), msg->header.typecookie);
+
+ /* At lower debugging levels, skip ASCII translation */
+ if (_gNgDebugLevel <= 2)
+ goto fail2;
+
+ /* If path is not absolute, don't bother trying to use relative
+ address on a different socket for the ASCII translation */
+ if (strchr(path, ':') == NULL)
+ goto fail2;
+
+ /* Get a temporary socket */
+ if (NgMkSockNode(NULL, &csock, NULL) < 0)
+ goto fail;
+
+ /* Copy binary message into request message payload */
+ arglen = msg->header.arglen;
+ if (arglen > ARGS_BUFSIZE)
+ arglen = ARGS_BUFSIZE;
+ memcpy(bin, msg, sizeof(*msg) + arglen);
+ bin->header.arglen = arglen;
+
+ /* Ask the node to translate the binary message to ASCII for us */
+ if (NgSendMsg(csock, path, NGM_GENERIC_COOKIE,
+ NGM_BINARY2ASCII, bin, sizeof(*bin) + bin->header.arglen) < 0)
+ goto fail;
+ if (NgRecvMsg(csock, req, sizeof(buf), NULL) < 0)
+ goto fail;
+
+ /* Display command string and arguments */
+ NGLOGX(" cmd %s (%d)", bin->header.cmdstr, bin->header.cmd);
+ NGLOGX(" args %s", bin->data);
+ goto done;
+
+fail:
+ /* Just display binary version */
+ NGLOGX(" [error decoding message: %s]", strerror(errno));
+fail2:
+ NGLOGX(" cmd %d", msg->header.cmd);
+ NGLOGX(" args (%d bytes)", msg->header.arglen);
+ _NgDebugBytes(msg->data, msg->header.arglen);
+
+done:
+ if (csock != -1)
+ (void)close(csock);
+ _gNgDebugLevel = debugSave;
}
/*
@@ -131,240 +244,20 @@ _NgDebugMsg(struct ng_mesg * msg)
static const char *
NgCookie(int cookie)
{
- static char buf[20];
-
- switch (cookie) {
- case NGM_GENERIC_COOKIE:
- return "generic";
- case NGM_TTY_COOKIE:
- return "tty";
- case NGM_ASYNC_COOKIE:
- return "async";
- case NGM_IFACE_COOKIE:
- return "iface";
- case NGM_FRAMERELAY_COOKIE:
- return "frame_relay";
- case NGM_LMI_COOKIE:
- return "lmi";
- case NGM_CISCO_COOKIE:
- return "cisco";
- case NGM_PPP_COOKIE:
- return "ppp";
- case NGM_RFC1490_NODE_COOKIE:
- return "rfc1490";
- case NGM_SOCKET_COOKIE:
- return "socket";
- }
- snprintf(buf, sizeof(buf), "?? (%d)", cookie);
- return buf;
-}
-
-/*
- * Return the name of the command
- */
-static const char *
-NgCmd(int cookie, int cmd)
-{
- static char buf[20];
-
- switch (cookie) {
- case NGM_GENERIC_COOKIE:
- switch (cmd) {
- case NGM_SHUTDOWN:
- return "shutdown";
- case NGM_MKPEER:
- return "mkpeer";
- case NGM_CONNECT:
- return "connect";
- case NGM_NAME:
- return "name";
- case NGM_RMHOOK:
- return "rmhook";
- case NGM_NODEINFO:
- return "nodeinfo";
- case NGM_LISTHOOKS:
- return "listhooks";
- case NGM_LISTNAMES:
- return "listnames";
- case NGM_LISTNODES:
- return "listnodes";
- case NGM_TEXT_STATUS:
- return "text_status";
- }
- break;
- case NGM_TTY_COOKIE:
- switch (cmd) {
- case NGM_TTY_GET_HOTCHAR:
- return "getHotChar";
- case NGM_TTY_SET_HOTCHAR:
- return "setHotChar";
- }
- break;
- case NGM_ASYNC_COOKIE:
- switch (cmd) {
- case NGM_ASYNC_CMD_GET_STATS:
- return "getStats";
- case NGM_ASYNC_CMD_CLR_STATS:
- return "setStats";
- case NGM_ASYNC_CMD_SET_CONFIG:
- return "setConfig";
- case NGM_ASYNC_CMD_GET_CONFIG:
- return "getConfig";
- }
- break;
- case NGM_IFACE_COOKIE:
- switch (cmd) {
- case NGM_IFACE_GET_IFNAME:
- return "getIfName";
- case NGM_IFACE_GET_IFADDRS:
- return "getIfAddrs";
- }
- break;
- case NGM_LMI_COOKIE:
- switch (cmd) {
- case NGM_LMI_GET_STATUS:
- return "get-status";
- }
- break;
- }
- snprintf(buf, sizeof(buf), "?? (%d)", cmd);
- return buf;
-}
-
-/*
- * Decode message arguments
- */
-static void
-NgArgs(int cookie, int cmd, int resp, void *args, int arglen)
-{
-
-switch (cookie) {
-case NGM_GENERIC_COOKIE:
- switch (cmd) {
- case NGM_SHUTDOWN:
- return;
- case NGM_MKPEER:
- {
- struct ngm_mkpeer *const mkp = (struct ngm_mkpeer *) args;
-
- if (resp)
- return;
- NGLOGX(" type \"%s\"", mkp->type);
- NGLOGX(" ourhook \"%s\"", mkp->ourhook);
- NGLOGX(" peerhook \"%s\"", mkp->peerhook);
- return;
- }
- case NGM_CONNECT:
- {
- struct ngm_connect *const ngc = (struct ngm_connect *) args;
-
- if (resp)
- return;
- NGLOGX(" path \"%s\"", ngc->path);
- NGLOGX(" ourhook \"%s\"", ngc->ourhook);
- NGLOGX(" peerhook \"%s\"", ngc->peerhook);
- return;
- }
- case NGM_NAME:
- {
- struct ngm_name *const ngn = (struct ngm_name *) args;
-
- if (resp)
- return;
- NGLOGX(" name \"%s\"", ngn->name);
- return;
- }
- case NGM_RMHOOK:
- {
- struct ngm_rmhook *const ngr = (struct ngm_rmhook *) args;
-
- if (resp)
- return;
- NGLOGX(" hook \"%s\"", ngr->ourhook);
- return;
- }
- case NGM_NODEINFO:
- return;
- case NGM_LISTHOOKS:
- return;
- case NGM_LISTNAMES:
- case NGM_LISTNODES:
- return;
- case NGM_TEXT_STATUS:
- if (!resp)
- return;
- NGLOGX(" status \"%s\"", (char *) args);
- return;
- }
- break;
-
-case NGM_TTY_COOKIE:
- switch (cmd) {
- case NGM_TTY_GET_HOTCHAR:
- if (!resp)
- return;
- NGLOGX(" char 0x%02x", *((int *) args));
- return;
- case NGM_TTY_SET_HOTCHAR:
- NGLOGX(" char 0x%02x", *((int *) args));
- return;
- }
- break;
-
-case NGM_ASYNC_COOKIE:
- switch (cmd) {
- case NGM_ASYNC_CMD_GET_STATS:
- {
- struct ng_async_stat *const as = (struct ng_async_stat *) args;
-
- if (!resp)
- return;
- NGLOGX(" syncOctets = %lu", as->syncOctets);
- NGLOGX(" syncFrames = %lu", as->syncFrames);
- NGLOGX(" syncOverflows = %lu", as->syncOverflows);
- NGLOGX(" asyncOctets = %lu", as->asyncOctets);
- NGLOGX(" asyncFrames = %lu", as->asyncFrames);
- NGLOGX(" asyncRunts = %lu", as->asyncRunts);
- NGLOGX(" asyncOverflows = %lu", as->asyncOverflows);
- NGLOGX(" asyncBadCheckSums = %lu", as->asyncBadCheckSums);
- return;
- }
- case NGM_ASYNC_CMD_GET_CONFIG:
- case NGM_ASYNC_CMD_SET_CONFIG:
- {
- struct ng_async_cfg *const ac = (struct ng_async_cfg *) args;
-
- if (!resp ^ (cmd != NGM_ASYNC_CMD_GET_CONFIG))
- return;
- NGLOGX(" enabled %s", ac->enabled ? "YES" : "NO");
- NGLOGX(" Async MRU %u", ac->amru);
- NGLOGX(" Sync MRU %u", ac->smru);
- NGLOGX(" ACCM 0x%08x", ac->accm);
- return;
- }
- case NGM_ASYNC_CMD_CLR_STATS:
- return;
- }
- break;
-
-case NGM_IFACE_COOKIE:
- switch (cmd) {
- case NGM_IFACE_GET_IFNAME:
- return;
- case NGM_IFACE_GET_IFADDRS:
- return;
- }
- break;
+ int k;
+ for (k = 0; cookies[k].cookie != 0; k++) {
+ if (cookies[k].cookie == cookie)
+ return cookies[k].type;
}
- _NgDebugBytes(args, arglen);
+ return "??";
}
/*
* Dump bytes in hex
*/
void
-_NgDebugBytes(const u_char * ptr, int len)
+_NgDebugBytes(const u_char *ptr, int len)
{
char buf[100];
int k, count;
diff --git a/lib/libnetgraph/internal.h b/lib/libnetgraph/internal.h
index 1022183..d521cfa 100644
--- a/lib/libnetgraph/internal.h
+++ b/lib/libnetgraph/internal.h
@@ -61,7 +61,7 @@ extern void (*_NgLogx)(const char *fmt, ...);
#define NGLOG (*_NgLog)
#define NGLOGX (*_NgLogx)
-extern void _NgDebugSockaddr(struct sockaddr_ng *sg);
-extern void _NgDebugMsg(struct ng_mesg *msg);
+extern void _NgDebugSockaddr(const struct sockaddr_ng *sg);
+extern void _NgDebugMsg(const struct ng_mesg *msg, const char *path);
extern void _NgDebugBytes(const u_char *ptr, int size);
diff --git a/lib/libnetgraph/msg.c b/lib/libnetgraph/msg.c
index 7eda707..ece1787 100644
--- a/lib/libnetgraph/msg.c
+++ b/lib/libnetgraph/msg.c
@@ -82,6 +82,66 @@ NgSendMsg(int cs, const char *path,
}
/*
+ * Send a message given in ASCII format. We first ask the node to translate
+ * the command into binary, and then we send the binary.
+ */
+int
+NgSendAsciiMsg(int cs, const char *path, const char *fmt, ...)
+{
+ const int bufSize = 1024;
+ char replybuf[2 * sizeof(struct ng_mesg) + bufSize];
+ struct ng_mesg *const reply = (struct ng_mesg *)replybuf;
+ struct ng_mesg *const binary = (struct ng_mesg *)reply->data;
+ struct ng_mesg *ascii;
+ char *buf, *cmd, *args;
+ va_list fmtargs;
+
+ /* Parse out command and arguments */
+ va_start(fmtargs, fmt);
+ vasprintf(&buf, fmt, fmtargs);
+ va_end(fmtargs);
+ if (buf == NULL)
+ return (-1);
+
+ /* Parse out command, arguments */
+ for (cmd = buf; isspace(*cmd); cmd++)
+ ;
+ for (args = cmd; *args != '\0' && !isspace(*args); args++)
+ ;
+ if (*args != '\0') {
+ while (isspace(*args))
+ *args++ = '\0';
+ }
+
+ /* Get a bigger buffer to hold inner message header plus arg string */
+ if ((ascii = malloc(sizeof(struct ng_mesg)
+ + strlen(buf) + 1)) == NULL) {
+ free(buf);
+ return (-1);
+ }
+ memset(ascii, 0, sizeof(*ascii));
+
+ /* Build inner header (only need cmdstr, arglen, and data fields) */
+ strncpy(ascii->header.cmdstr, cmd, sizeof(ascii->header.cmdstr) - 1);
+ strcpy(ascii->data, args);
+ ascii->header.arglen = strlen(ascii->data) + 1;
+ free(buf);
+
+ /* Send node a request to convert ASCII to binary */
+ if (NgSendMsg(cs, path, NGM_GENERIC_COOKIE, NGM_ASCII2BINARY,
+ (u_char *)ascii, sizeof(*ascii) + ascii->header.arglen) < 0)
+ return (-1);
+
+ /* Get reply */
+ if (NgRecvMsg(cs, reply, sizeof(replybuf), NULL) < 0)
+ return (-1);
+
+ /* Now send binary version */
+ return NgDeliverMsg(cs,
+ path, binary, binary->data, binary->header.arglen);
+}
+
+/*
* Send a message that is a reply to a previously received message.
* Returns -1 and sets errno on error, otherwise returns zero.
*/
@@ -143,7 +203,7 @@ NgDeliverMsg(int cs, const char *path,
NGLOGX("SENDING %s:",
(msg->header.flags & NGF_RESP) ? "RESPONSE" : "MESSAGE");
_NgDebugSockaddr(sg);
- _NgDebugMsg(msg);
+ _NgDebugMsg(msg, sg->sg_data);
}
/* Send it */
@@ -193,7 +253,7 @@ NgRecvMsg(int cs, struct ng_mesg *rep, size_t replen, char *path)
NGLOGX("RECEIVED %s:",
(rep->header.flags & NGF_RESP) ? "RESPONSE" : "MESSAGE");
_NgDebugSockaddr(sg);
- _NgDebugMsg(rep);
+ _NgDebugMsg(rep, sg->sg_data);
}
/* Done */
@@ -204,3 +264,48 @@ errout:
return (-1);
}
+/*
+ * Receive a control message and convert the arguments to ASCII
+ */
+int
+NgRecvAsciiMsg(int cs, struct ng_mesg *reply, size_t replen, char *path)
+{
+ struct ng_mesg *msg, *ascii;
+ int bufSize, errnosv;
+ u_char *buf;
+
+ /* Allocate buffer */
+ bufSize = 2 * sizeof(*reply) + replen;
+ if ((buf = malloc(bufSize)) == NULL)
+ return (-1);
+ msg = (struct ng_mesg *)buf;
+ ascii = (struct ng_mesg *)msg->data;
+
+ /* Get binary message */
+ if (NgRecvMsg(cs, msg, bufSize, path) < 0)
+ goto fail;
+ memcpy(reply, msg, sizeof(*msg));
+
+ /* Ask originating node to convert the arguments to ASCII */
+ if (NgSendMsg(cs, path, NGM_GENERIC_COOKIE,
+ NGM_BINARY2ASCII, msg, sizeof(*msg) + msg->header.arglen) < 0)
+ goto fail;
+ if (NgRecvMsg(cs, msg, bufSize, NULL) < 0)
+ goto fail;
+
+ /* Copy result to client buffer */
+ if (sizeof(*ascii) + ascii->header.arglen > replen) {
+ errno = ERANGE;
+fail:
+ errnosv = errno;
+ free(buf);
+ errno = errnosv;
+ return (-1);
+ }
+ strncpy(reply->data, ascii->data, ascii->header.arglen);
+
+ /* Done */
+ free(buf);
+ return (0);
+}
+
diff --git a/lib/libnetgraph/netgraph.3 b/lib/libnetgraph/netgraph.3
index dc9df04..6926f96 100644
--- a/lib/libnetgraph/netgraph.3
+++ b/lib/libnetgraph/netgraph.3
@@ -57,10 +57,14 @@
.Ft int
.Fn NgSendMsg "int cs" "const char *path" "int cookie" "int cmd" "const void *arg" "size_t arglen"
.Ft int
+.Fn NgSendAsciiMsg "int cs" "const char *path" "const char *fmt" "..."
+.Ft int
.Fn NgSendMsgReply "int cs" "const char *path" "struct ng_mesg *msg" "const void *arg" "size_t arglen"
.Ft int
.Fn NgRecvMsg "int cs" "struct ng_mesg *rep" "size_t replen" "char *path"
.Ft int
+.Fn NgRecvAsciiMsg "int cs" "struct ng_mesg *rep" "size_t replen" "char *path"
+.Ft int
.Fn NgSendData "int ds" "const char *hook" "const u_char *buf" "size_t len"
.Ft int
.Fn NgRecvData "int ds" "u_char *buf" "size_t len" "char *hook"
@@ -97,7 +101,8 @@ assigns a global name to the node addressed by
.Fa path .
.Pp
.Fn NgSendMsg
-sends a control message from the socket node associated with control socket
+sends a binary control message from the socket node associated
+with control socket
.Fa cs
to the node addressed by
.Fa path .
@@ -122,6 +127,20 @@ to send reply to a previously received control message.
The original message header should be pointed to by
.Fa msg .
.Pp
+.Fn NgSendAsciiMsg
+performs the same function as
+.Fn NgSendMsg ,
+but adds support for ASCII encoding of control messages.
+.Fn NgSendAsciiMsg
+formats its input a la
+.Xr printf 3
+and then sends the resulting ASCII string to the node in a
+.Dv NGM_ASCII2BINARY
+control message. The node returns a binary version of the
+message, which is then sent back to the node just as with
+.Fn NgSendMsg .
+Note that ASCII conversion may not be supported by all node types.
+.Pp
.Fn NgRecvMsg
reads the next control message received by the node associated with
control socket
@@ -136,6 +155,18 @@ is non-NULL, it must point to a buffer of at least
bytes, which will be filled in (and NUL terminated) with the path to
the node from which the message was received.
.Pp
+.Fn NgRecvAsciiMsg
+works exactly like
+.Fn NgRecvMsg ,
+except that after the message is received, any binary arguments
+are converted to ASCII by sending a
+.Dv NGM_BINARY2ASCII
+request back to the originating node. The result is the same as
+.Fn NgRecvAsciiMsg ,
+with the exception that the reply arguments field will contain
+a NUL-terminated ASCII version of the arguments (and the reply
+header argument length field will be adjusted).
+.Pp
.Fn NgSendData
writes a data packet out on the specified hook of the node corresponding
to data socket
@@ -171,6 +202,11 @@ The default logging functions are
and
.Xr vwarnx 3 .
.Pp
+At debug level 3, the library attempts to display control message arguments
+in ASCII format; however, this results in additional messages being
+sent which may interfere with debugging. At even higher levels,
+even these additional messagages will be displayed, etc.
+.Pp
Note that
.Xr select 2
can be used on the data and the control sockets to detect the presence of
@@ -182,9 +218,9 @@ User mode programs must be linked with the
.Dv -lnetgraph
flag to link in this library.
.Sh INITIALIZATION
-Netgraph is not part of the standard FreeBSD kernel. To enable it,
-either your kernel must be compiled with ``options NETGRAPH''
-in the kernel configuration file, or else the
+To enable Netgraph in your kernel, either your kernel must be
+compiled with ``options NETGRAPH'' in the kernel configuration
+file, or else the
.Xr netgraph 4
and
.Xr ng_socket 8
@@ -196,6 +232,26 @@ All functions except
and
.Fn NgSetErrLog
return -1 if there was an error and set errno accordingly.
+.Pp
+For
+.Fn NgSendAsciiMsg
+and
+.Fn NgRecvAsciiMsg ,
+the following additional errors are possible:
+.Bl -tag -width Er
+.It Bq Er ENOSYS
+The node type does not know how to encode or decode the control message.
+.It Bq Er ERANGE
+The encoded or decoded arguments were too long for the supplied buffer.
+.It Bq Er ENOENT
+An unknown structure field was seen in an ASCII control message.
+.It Bq Er EALREADY
+The same structure field was specified twice in an ASCII control message.
+.It Bq Er EINVAL
+ASCII control message parse error or illegal value.
+.It Bq Er E2BIG
+ASCII control message array or fixed width string buffer overflow.
+.El
.Sh SEE ALSO
.Xr netgraph 4 ,
.Xr socket 2 ,
@@ -205,7 +261,7 @@ return -1 if there was an error and set errno accordingly.
.Sh HISTORY
The
.Em netgraph
-system was designed and first implemented at Whistle Communications, Inc.
-in a version FreeBSD 2.2 customized for the Whistle InterJet.
+system was designed and first implemented at Whistle Communications, Inc. in
+a version FreeBSD 2.2 customized for the Whistle InterJet.
.Sh AUTHOR
.An Archie Cobbs <archie@whistle.com>
diff --git a/lib/libnetgraph/netgraph.h b/lib/libnetgraph/netgraph.h
index f60f04b..c5a87cb 100644
--- a/lib/libnetgraph/netgraph.h
+++ b/lib/libnetgraph/netgraph.h
@@ -50,9 +50,11 @@ __BEGIN_DECLS
int NgMkSockNode(const char *, int *, int *);
int NgNameNode(int, const char *, const char *, ...);
int NgSendMsg(int, const char *, int, int, const void *, size_t);
+int NgSendAsciiMsg(int, const char *, const char *, ...);
int NgSendReplyMsg(int, const char *,
const struct ng_mesg *, const void *, size_t);
int NgRecvMsg(int, struct ng_mesg *, size_t, char *);
+int NgRecvAsciiMsg(int, struct ng_mesg *, size_t, char *);
int NgSendData(int, const char *, const u_char *, size_t);
int NgRecvData(int, u_char *, size_t, char *);
int NgSetDebug(int);
OpenPOWER on IntegriCloud