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