#include <sys/types.h>
#include <sys/time.h>
#include <sys/ioctl.h>
#include <stdarg.h>
#include <netinet/in.h>
#include <net/ethernet.h>
#include <net/bpf.h>
#include <netgraph/ng_message.h>
#include <netgraph/ng_socket.h>
#include "netgraph.h"
#include "internal.h"
#include <netgraph/ng_UI.h>
#include <netgraph/ng_async.h>
#include <netgraph/ng_bpf.h>
#include <netgraph/ng_bridge.h>
#include <netgraph/ng_car.h>
#include <netgraph/ng_cisco.h>
#include <netgraph/ng_deflate.h>
#include <netgraph/ng_device.h>
#include <netgraph/ng_echo.h>
#include <netgraph/ng_eiface.h>
#include <netgraph/ng_etf.h>
#include <netgraph/ng_ether.h>
#include <netgraph/ng_ether_echo.h>
#include <netgraph/ng_frame_relay.h>
#include <netgraph/ng_gif.h>
#include <netgraph/ng_gif_demux.h>
#include <netgraph/ng_hole.h>
#include <netgraph/ng_hub.h>
#include <netgraph/ng_iface.h>
#include <netgraph/ng_ip_input.h>
#include <netgraph/ng_ipfw.h>
#include <netgraph/ng_ksocket.h>
#include <netgraph/ng_l2tp.h>
#include <netgraph/ng_lmi.h>
#include <netgraph/ng_mppc.h>
#include <netgraph/ng_nat.h>
#include <netgraph/netflow/ng_netflow.h>
#include <netgraph/ng_one2many.h>
#include <netgraph/ng_patch.h>
#include <netgraph/ng_pipe.h>
#include <netgraph/ng_ppp.h>
#include <netgraph/ng_pppoe.h>
#include <netgraph/ng_pptpgre.h>
#include <netgraph/ng_pred1.h>
#include <netgraph/ng_rfc1490.h>
#include <netgraph/ng_socket.h>
#include <netgraph/ng_source.h>
#include <netgraph/ng_split.h>
#include <netgraph/ng_tag.h>
#include <netgraph/ng_tcpmss.h>
#include <netgraph/ng_tee.h>
#include <netgraph/ng_tty.h>
#include <netgraph/ng_vjc.h>
#include <netgraph/ng_vlan.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_tn.h>
#endif
int _gNgDebugLevel = 0;
void (*_NgLog) (const char *fmt,...) = warn;
void (*_NgLogx) (const char *fmt,...) = warnx;
static const char *NgCookie(int cookie);
struct ng_cookie {
int cookie;
const char *type;
};
#define COOKIE(c) { NGM_ ## c ## _COOKIE, #c }
static const struct ng_cookie cookies[] = {
COOKIE(UI),
COOKIE(ASYNC),
COOKIE(BPF),
COOKIE(BRIDGE),
COOKIE(CAR),
COOKIE(CISCO),
COOKIE(DEFLATE),
COOKIE(DEVICE),
COOKIE(ECHO),
COOKIE(EIFACE),
COOKIE(ETF),
COOKIE(ETHER),
COOKIE(ETHER_ECHO),
COOKIE(FRAMERELAY),
COOKIE(GIF),
COOKIE(GIF_DEMUX),
COOKIE(GENERIC),
COOKIE(HOLE),
COOKIE(HUB),
COOKIE(IFACE),
COOKIE(IP_INPUT),
COOKIE(IPFW),
COOKIE(KSOCKET),
COOKIE(L2TP),
COOKIE(LMI),
COOKIE(MPPC),
COOKIE(NAT),
COOKIE(NETFLOW),
COOKIE(ONE2MANY),
COOKIE(PATCH),
COOKIE(PIPE),
COOKIE(PPP),
COOKIE(PPPOE),
COOKIE(PPTPGRE),
COOKIE(PRED1),
COOKIE(RFC1490),
COOKIE(SOCKET),
COOKIE(SOURCE),
COOKIE(SPLIT),
COOKIE(TAG),
COOKIE(TCPMSS),
COOKIE(TEE),
COOKIE(TTY),
COOKIE(VJC),
COOKIE(VLAN),
#ifdef WHISTLE
COOKIE(DF),
COOKIE(IPAC),
COOKIE(TN),
COOKIE(WFRA),
#endif
{ 0, NULL }
};
int
NgSetDebug(int level)
{
int old = _gNgDebugLevel;
if (level >= 0)
_gNgDebugLevel = level;
return (old);
}
void
NgSetErrLog(void (*log) (const char *fmt,...),
void (*logx) (const char *fmt,...))
{
_NgLog = log;
_NgLogx = logx;
}
void
_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 2048
#define RECURSIVE_DEBUG_ADJUST 4
void
_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, csock = -1;
NGLOGX("NG_MESG :");
NGLOGX(" vers %d", msg->header.version);
NGLOGX(" arglen %u", msg->header.arglen);
NGLOGX(" flags %x", msg->header.flags);
NGLOGX(" token %u", msg->header.token);
NGLOGX(" cookie %s (%u)",
NgCookie(msg->header.typecookie), msg->header.typecookie);
if (_gNgDebugLevel <= 2)
goto fail2;
if (strchr(path, ':') == NULL)
goto fail2;
if (NgMkSockNode(NULL, &csock, NULL) < 0)
goto fail;
arglen = msg->header.arglen;
if (arglen > ARGS_BUFSIZE)
arglen = ARGS_BUFSIZE;
memcpy(bin, msg, sizeof(*msg) + arglen);
bin->header.arglen = arglen;
_gNgDebugLevel -= RECURSIVE_DEBUG_ADJUST;
if (NgSendMsg(csock, path, NGM_GENERIC_COOKIE,
NGM_BINARY2ASCII, bin, sizeof(*bin) + bin->header.arglen) < 0) {
_gNgDebugLevel += RECURSIVE_DEBUG_ADJUST;
goto fail;
}
if (NgRecvMsg(csock, req, sizeof(buf), NULL) < 0) {
_gNgDebugLevel += RECURSIVE_DEBUG_ADJUST;
goto fail;
}
_gNgDebugLevel += RECURSIVE_DEBUG_ADJUST;
NGLOGX(" cmd %s (%d)", bin->header.cmdstr, bin->header.cmd);
NGLOGX(" args %s", bin->data);
goto done;
fail:
NGLOGX(" [error decoding message: %s]", strerror(errno));
fail2:
NGLOGX(" cmd %d", msg->header.cmd);
NGLOGX(" args (%d bytes)", msg->header.arglen);
_NgDebugBytes((u_char *)msg->data, msg->header.arglen);
done:
if (csock != -1)
(void)close(csock);
}
static const char *
NgCookie(int cookie)
{
int k;
for (k = 0; cookies[k].cookie != 0; k++) {
if (cookies[k].cookie == cookie)
return cookies[k].type;
}
return "??";
}
void
_NgDebugBytes(const u_char *ptr, int len)
{
char buf[100];
int k, count;
#define BYPERLINE 16
for (count = 0; count < len; ptr += BYPERLINE, count += BYPERLINE) {
snprintf(buf, sizeof(buf), "%04x: ", count);
for (k = 0; k < BYPERLINE; k++, count++)
if (count < len)
snprintf(buf + strlen(buf),
sizeof(buf) - strlen(buf), "%02x ", ptr[k]);
else
snprintf(buf + strlen(buf),
sizeof(buf) - strlen(buf), " ");
snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), " ");
count -= BYPERLINE;
for (k = 0; k < BYPERLINE; k++, count++)
if (count < len)
snprintf(buf + strlen(buf),
sizeof(buf) - strlen(buf),
"%c", isprint(ptr[k]) ? ptr[k] : '.');
else
snprintf(buf + strlen(buf),
sizeof(buf) - strlen(buf), " ");
count -= BYPERLINE;
NGLOGX("%s", buf);
}
}