/* * 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); }
/* * 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); }
/* * 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); }