예제 #1
0
파일: sock.c 프로젝트: edgar-pek/PerspicuOS
/*
 * Write a packet to a data socket. The packet will be sent
 * out the corresponding node on the specified hook.
 * Returns -1 if error and sets errno.
 */
int
NgSendData(int ds, const char *hook, const u_char * buf, size_t len)
{
	u_char sgbuf[NG_HOOKSIZ + NGSA_OVERHEAD];
	struct sockaddr_ng *const sg = (struct sockaddr_ng *) sgbuf;
	int errnosv;

	/* Set up destination hook */
	sg->sg_family = AF_NETGRAPH;
	strlcpy(sg->sg_data, hook, NG_HOOKSIZ);
	sg->sg_len = strlen(sg->sg_data) + 1 + NGSA_OVERHEAD;

	/* Debugging */
	if (_gNgDebugLevel >= 2) {
		NGLOGX("WRITE PACKET to hook \"%s\" (%d bytes)", hook, len);
		_NgDebugSockaddr(sg);
		if (_gNgDebugLevel >= 3)
			_NgDebugBytes(buf, len);
	}

	/* Send packet */
	if (sendto(ds, buf, len, 0, (struct sockaddr *) sg, sg->sg_len) < 0) {
		errnosv = errno;
		if (_gNgDebugLevel >= 1)
			NGLOG("sendto(%s)", sg->sg_data);
		errno = errnosv;
		return (-1);
	}

	/* Done */
	return (0);
}
예제 #2
0
파일: msg.c 프로젝트: ele7enxxh/dtrace-pf
/*
 * Receive a control message.
 *
 * On error, this returns -1 and sets errno.
 * Otherwise, it returns the length of the received reply.
 */
int
NgRecvMsg(int cs, struct ng_mesg *rep, size_t replen, char *path)
{
	u_char sgbuf[NG_PATHSIZ + NGSA_OVERHEAD];
	struct sockaddr_ng *const sg = (struct sockaddr_ng *) sgbuf;
	socklen_t sglen = sizeof(sgbuf);
	int len, errnosv;

	/* Read reply */
	len = recvfrom(cs, rep, replen, 0, (struct sockaddr *) sg, &sglen);
	if (len < 0) {
		errnosv = errno;
		if (_gNgDebugLevel >= 1)
			NGLOG("recvfrom");
		goto errout;
	}
	if (path != NULL)
		strlcpy(path, sg->sg_data, NG_PATHSIZ);

	/* Debugging */
	if (_gNgDebugLevel >= 2) {
		NGLOGX("RECEIVED %s:",
		    (rep->header.flags & NGF_RESP) ? "RESPONSE" : "MESSAGE");
		_NgDebugSockaddr(sg);
		_NgDebugMsg(rep, sg->sg_data);
	}

	/* Done */
	return (len);

errout:
	errno = errnosv;
	return (-1);
}
예제 #3
0
파일: sock.c 프로젝트: edgar-pek/PerspicuOS
/*
 * Read a packet from a data socket
 * Returns -1 if error and sets errno.
 */
int
NgRecvData(int ds, u_char * buf, size_t len, char *hook)
{
	u_char frombuf[NG_HOOKSIZ + NGSA_OVERHEAD];
	struct sockaddr_ng *const from = (struct sockaddr_ng *) frombuf;
	socklen_t fromlen = sizeof(frombuf);
	int rtn, errnosv;

	/* Read packet */
	rtn = recvfrom(ds, buf, len, 0, (struct sockaddr *) from, &fromlen);
	if (rtn < 0) {
		errnosv = errno;
		if (_gNgDebugLevel >= 1)
			NGLOG("recvfrom");
		errno = errnosv;
		return (-1);
	}

	/* Copy hook name */
	if (hook != NULL)
		strlcpy(hook, from->sg_data, NG_HOOKSIZ);

	/* Debugging */
	if (_gNgDebugLevel >= 2) {
		NGLOGX("READ %s from hook \"%s\" (%d bytes)",
		       rtn ? "PACKET" : "EOF", from->sg_data, rtn);
		if (_gNgDebugLevel >= 3)
			_NgDebugBytes(buf, rtn);
	}

	/* Done */
	return (rtn);
}
예제 #4
0
파일: sock.c 프로젝트: edgar-pek/PerspicuOS
/*
 * Assign a globally unique name to a node
 * Returns -1 if error and sets errno.
 */
int
NgNameNode(int cs, const char *path, const char *fmt, ...)
{
	struct ngm_name ngn;
	va_list args;

	/* Build message arg */
	va_start(args, fmt);
	vsnprintf(ngn.name, sizeof(ngn.name), fmt, args);
	va_end(args);

	/* Send message */
	if (NgSendMsg(cs, path,
	    NGM_GENERIC_COOKIE, NGM_NAME, &ngn, sizeof(ngn)) < 0) {
		if (_gNgDebugLevel >= 1)
			NGLOGX("%s: failed", __func__);
		return (-1);
	}

	/* Done */
	return (0);
}
예제 #5
0
/*
 * Dump bytes in hex
 */
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) {

		/* Do hex */
		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;

		/* Do ASCII */
		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;

		/* Print it */
		NGLOGX("%s", buf);
	}
}
예제 #6
0
/*
 * Display a negraph message
 */
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;

	/* Display header stuff */
	NGLOGX("NG_MESG :");
	NGLOGX("  vers   %d", msg->header.version);
	NGLOGX("  arglen %d", msg->header.arglen);
	NGLOGX("  flags  %u", msg->header.flags);
	NGLOGX("  token  %u", 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;

	/* Lower debugging to avoid infinite recursion */
	_gNgDebugLevel -= RECURSIVE_DEBUG_ADJUST;

	/* 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) {
		_gNgDebugLevel += RECURSIVE_DEBUG_ADJUST;
		goto fail;
	}
	if (NgRecvMsg(csock, req, sizeof(buf), NULL) < 0) {
		_gNgDebugLevel += RECURSIVE_DEBUG_ADJUST;
		goto fail;
	}

	/* Restore debugging level */
	_gNgDebugLevel += RECURSIVE_DEBUG_ADJUST;

	/* 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);
}
예제 #7
0
/*
 * Display a netgraph sockaddr
 */
void
_NgDebugSockaddr(const struct sockaddr_ng *sg)
{
	NGLOGX("SOCKADDR: { fam=%d len=%d addr=\"%s\" }",
	       sg->sg_family, sg->sg_len, sg->sg_data);
}
예제 #8
0
파일: msg.c 프로젝트: ele7enxxh/dtrace-pf
/*
 * Send a message to a node using control socket node "cs".
 * Returns -1 if error and sets errno appropriately, otherwise zero.
 */
static int
NgDeliverMsg(int cs, const char *path,
	const struct ng_mesg *hdr, const void *args, size_t arglen)
{
	u_char sgbuf[NG_PATHSIZ + NGSA_OVERHEAD];
	struct sockaddr_ng *const sg = (struct sockaddr_ng *) sgbuf;
	u_char *buf = NULL;
	struct ng_mesg *msg;
	int errnosv = 0;
	int rtn = 0;

	/* Sanity check */
	if (args == NULL)
		arglen = 0;

	/* Get buffer */
	if ((buf = malloc(sizeof(*msg) + arglen)) == NULL) {
		errnosv = errno;
		if (_gNgDebugLevel >= 1)
			NGLOG("malloc");
		rtn = -1;
		goto done;
	}
	msg = (struct ng_mesg *) buf;

	/* Finalize message */
	*msg = *hdr;
	msg->header.arglen = arglen;
	memcpy(msg->data, args, arglen);

	/* Prepare socket address */
	sg->sg_family = AF_NETGRAPH;
	/* XXX handle overflow */
	strlcpy(sg->sg_data, path, NG_PATHSIZ);
	sg->sg_len = strlen(sg->sg_data) + 1 + NGSA_OVERHEAD;

	/* Debugging */
	if (_gNgDebugLevel >= 2) {
		NGLOGX("SENDING %s:",
		    (msg->header.flags & NGF_RESP) ? "RESPONSE" : "MESSAGE");
		_NgDebugSockaddr(sg);
		_NgDebugMsg(msg, sg->sg_data);
	}

	/* Send it */
	if (sendto(cs, msg, sizeof(*msg) + arglen,
		   0, (struct sockaddr *) sg, sg->sg_len) < 0) {
		errnosv = errno;
		if (_gNgDebugLevel >= 1)
			NGLOG("sendto(%s)", sg->sg_data);
		rtn = -1;
		goto done;
	}

	/* Wait for reply if there should be one. */
	if (msg->header.cmd & NGM_HASREPLY && !(msg->header.flags & NGF_RESP)) {
		struct pollfd rfds;
		int n;

		rfds.fd = cs;
		rfds.events = POLLIN;
		rfds.revents = 0;
		n = poll(&rfds, 1, INFTIM);
		if (n == -1) {
			errnosv = errno;
			if (_gNgDebugLevel >= 1)
				NGLOG("poll");
			rtn = -1;
		}
	}

done:
	/* Done */
	free(buf);		/* OK if buf is NULL */
	errno = errnosv;
	return (rtn);
}