int main ( int argc, char *argv[] ) { char *socketToGet; char sockName[NG_PATHSIZ]; if ( argc < 2 ) { socketToGet = "[98]:"; } else { socketToGet = argv[1]; } memset( sockName, 0, sizeof(sockName)); sprintf(sockName, "%s%d", "getsockopt", getpid()); // "[0008ecf4]:" if ( NgMkSockNode("getsockopt-node", &csock, &dsock) < 0 ) { printf("Error has occured while creating netgraph socket: %s\n", strerror(errno)); return 1; } GetKsocketTos(socketToGet); //GetKsocketError(socketToGet); /* GetKsocketKeepAlive(socketToGet); SetKsocketKeepAlive(socketToGet); GetKsocketKeepAlive(socketToGet); */ //GetKsocketTcpInfo(socketToGet); return 1; }
int CreateNgSock() { char name[NG_PATHSIZ]; memset(name, 0, sizeof(name)); sprintf(name, "%s-%d", "http_server", getpid()); if ( NgMkSockNode(name, &csock, &dsock) < 0) { printf("Error has occured while creating NgSocket: %s\n", strerror(errno)); exit(1); } }
int ID0NgMkSockNode(const char *name, int *cs, int *ds) { int result; ID0set0(); result = NgMkSockNode(name, cs, ds); log_Printf(LogID0, "%d = NgMkSockNode(\"%s\", &cs, &ds)\n", result, name ? name : ""); ID0setuser(); return result; }
void RepIncoming(Link l) { Rep r = l->rep; struct ngm_mkpeer mkp; char buf[64]; Log(LG_REP, ("[%s] Rep: INCOMING event from %s (0)", r->name, l->name)); if (r->csock <= 0) { /* Create a new netgraph node to control TCP ksocket node. */ if (NgMkSockNode(NULL, &r->csock, NULL) < 0) { Perror("[%s] Rep: can't create control socket", r->name); PhysClose(l); return; } (void)fcntl(r->csock, F_SETFD, 1); } strcpy(mkp.type, NG_TEE_NODE_TYPE); snprintf(mkp.ourhook, sizeof(mkp.ourhook), "tee"); snprintf(mkp.peerhook, sizeof(mkp.peerhook), NG_TEE_HOOK_LEFT2RIGHT); if (NgSendMsg(r->csock, ".:", NGM_GENERIC_COOKIE, NGM_MKPEER, &mkp, sizeof(mkp)) < 0) { Perror("[%s] Rep: can't attach %s %s node", l->name, NG_TEE_NODE_TYPE, mkp.ourhook); close(r->csock); PhysClose(l); return; } /* Get tee node ID */ if ((r->node_id = NgGetNodeID(r->csock, ".:tee")) == 0) { Perror("[%s] Rep: Cannot get %s node id", l->name, NG_TEE_NODE_TYPE); close(r->csock); PhysClose(l); return; }; PhysGetCallingNum(r->links[0], buf, sizeof(buf)); PhysSetCallingNum(r->links[1], buf); PhysGetCalledNum(r->links[0], buf, sizeof(buf)); PhysSetCalledNum(r->links[1], buf); PhysOpen(r->links[1]); }
int main(int argc, char **argv) { struct ngm_connect ngc; int ngs; int csp, dsp; char path[256]; ngs = NgMkSockNode("prout", &csp, &dsp); snprintf(path, sizeof(path), "fv_vrid1_eiface:"); snprintf(ngc.path, sizeof(ngc.path), "em0bridge:"); snprintf(ngc.ourhook, sizeof(ngc.ourhook), "ether"); snprintf(ngc.peerhook, sizeof(ngc.peerhook), "link2"); if (NgSendMsg(csp, path, NGM_GENERIC_COOKIE, NGM_CONNECT, &ngc, sizeof(ngc)) < 0) perror("NgSendMsg"); return 0; }
int main(int argc, char **argv) { int c; char sname[NG_NODESIZ]; int rcvbuf = SORCVBUF_SIZE; /* parse options */ while ((c = getopt(argc, argv, "d:")) != -1) { switch (c) { case 'd': /* set libnetgraph debug level. */ NgSetDebug(atoi(optarg)); break; } } argc -= optind; argv += optind; ng_path = argv[0]; if (ng_path == NULL || (strlen(ng_path) > NG_PATHSIZ)) help(); argc--; argv++; /* create control socket. */ snprintf(sname, sizeof(sname), "flowctl%i", getpid()); if (NgMkSockNode(sname, &cs, NULL) == -1) err(1, "NgMkSockNode"); /* set receive buffer size */ if (setsockopt(cs, SOL_SOCKET, SO_RCVBUF, &rcvbuf, sizeof(int)) == -1) err(1, "setsockopt(SOL_SOCKET, SO_RCVBUF)"); /* parse and execute command */ execute_command(argc, argv); close(cs); exit(0); }
int CcpsInit(void) { char name[NG_NODESIZ]; /* Create a netgraph socket node */ snprintf(name, sizeof(name), "mpd%d-cso", gPid); if (NgMkSockNode(name, &gCcpCsock, &gCcpDsock) < 0) { Perror("CcpsInit(): can't create %s node", NG_SOCKET_NODE_TYPE); return(-1); } (void) fcntl(gCcpCsock, F_SETFD, 1); (void) fcntl(gCcpDsock, F_SETFD, 1); /* Listen for happenings on our node */ EventRegister(&gCcpCtrlEvent, EVENT_READ, gCcpCsock, EVENT_RECURRING, CcpNgCtrlEvent, NULL); EventRegister(&gCcpDataEvent, EVENT_READ, gCcpDsock, EVENT_RECURRING, CcpNgDataEvent, NULL); return (0); }
/* * main() */ int main(int ac, char *av[]) { char name[NG_NODESIZ]; int interactive = isatty(0) && isatty(1); FILE *fp = NULL; int ch, rtn = 0; /* Set default node name */ snprintf(name, sizeof(name), "ngctl%d", getpid()); /* Parse command line */ while ((ch = getopt(ac, av, "df:n:")) != -1) { switch (ch) { case 'd': NgSetDebug(NgSetDebug(-1) + 1); break; case 'f': if (strcmp(optarg, "-") == 0) fp = stdin; else if ((fp = fopen(optarg, "r")) == NULL) err(EX_NOINPUT, "%s", optarg); break; case 'n': snprintf(name, sizeof(name), "%s", optarg); break; case '?': default: Usage((char *)NULL); break; } } ac -= optind; av += optind; /* Create a new socket node */ if (NgMkSockNode(name, &csock, &dsock) < 0) err(EX_OSERR, "can't create node"); /* Do commands as requested */ if (ac == 0) { if (fp != NULL) { rtn = ReadFile(fp); } else if (interactive) { rtn = DoInteractive(); } else Usage("no command specified"); } else { rtn = DoCommand(ac, av); } /* Convert command return code into system exit code */ switch (rtn) { case CMDRTN_OK: case CMDRTN_QUIT: rtn = 0; break; case CMDRTN_USAGE: rtn = EX_USAGE; break; case CMDRTN_ERROR: rtn = EX_OSERR; break; } return (rtn); }
void netgraphprotopr(u_long off, const char *name, int af1 __unused, int proto __unused) { struct ngpcb *this, *next; struct ngpcb ngpcb; struct socket sockb; int debug = 1; /* If symbol not found, try looking in the KLD module */ if (off == 0) { if (debug) fprintf(stderr, "Error reading symbols from ng_socket.ko"); return; } /* Get pointer to first socket */ kread(off, (char *)&this, sizeof(this)); /* Get my own socket node */ if (csock == -1) NgMkSockNode(NULL, &csock, NULL); for (; this != NULL; this = next) { u_char rbuf[sizeof(struct ng_mesg) + sizeof(struct nodeinfo)]; struct ng_mesg *resp = (struct ng_mesg *) rbuf; struct nodeinfo *ni = (struct nodeinfo *) resp->data; char path[64]; /* Read in ngpcb structure */ kread((u_long)this, (char *)&ngpcb, sizeof(ngpcb)); next = LIST_NEXT(&ngpcb, socks); /* Read in socket structure */ kread((u_long)ngpcb.ng_socket, (char *)&sockb, sizeof(sockb)); /* Check type of socket */ if (strcmp(name, "ctrl") == 0 && ngpcb.type != NG_CONTROL) continue; if (strcmp(name, "data") == 0 && ngpcb.type != NG_DATA) continue; /* Do headline */ if (first) { printf("Netgraph sockets\n"); if (Aflag) printf("%-8.8s ", "PCB"); printf("%-5.5s %-6.6s %-6.6s %-14.14s %s\n", "Type", "Recv-Q", "Send-Q", "Node Address", "#Hooks"); first = 0; } /* Show socket */ if (Aflag) printf("%8lx ", (u_long) this); printf("%-5.5s %6u %6u ", name, sockb.so_rcv.sb_cc, sockb.so_snd.sb_cc); /* Get info on associated node */ if (ngpcb.node_id == 0 || csock == -1) goto finish; snprintf(path, sizeof(path), "[%x]:", ngpcb.node_id); if (NgSendMsg(csock, path, NGM_GENERIC_COOKIE, NGM_NODEINFO, NULL, 0) < 0) goto finish; if (NgRecvMsg(csock, resp, sizeof(rbuf), NULL) < 0) goto finish; /* Display associated node info */ if (*ni->name != '\0') snprintf(path, sizeof(path), "%s:", ni->name); printf("%-14.14s %4d", path, ni->hooks); finish: putchar('\n'); } }
int main(int argc, char *argv[]) { char hostname[MAXHOSTNAMELEN], *exec, rhook[NG_HOOKSIZ]; unsigned char response[1024]; const char *label, *prog, *provider, *acname; struct ngm_connect ngc; struct sigaction act; int ch, cs, ds, ret, optF, optd, optn, sz, f; const char *pidfile; prog = strrchr(argv[0], '/'); prog = prog ? prog + 1 : argv[0]; pidfile = NULL; exec = NULL; label = NULL; acname = NULL; provider = ""; optF = optd = optn = 0; while ((ch = getopt(argc, argv, "FP:a:de:l:n:p:")) != -1) { switch (ch) { case 'F': optF = 1; break; case 'P': pidfile = optarg; break; case 'a': acname = optarg; break; case 'd': optd = 1; break; case 'e': exec = optarg; break; case 'l': label = optarg; break; case 'n': optn = 1; NgSetDebug(atoi(optarg)); break; case 'p': provider = optarg; break; default: return usage(prog); } } if (optind >= argc || optind + 2 < argc) return usage(prog); if (exec != NULL && label != NULL) return usage(prog); if (exec == NULL) { if (label == NULL) label = provider; if (label == NULL) { fprintf(stderr, "%s: Either a provider, a label or an exec command" " must be given\n", prog); return usage(prog); } exec = (char *)alloca(sizeof DEFAULT_EXEC_PREFIX + strlen(label)); if (exec == NULL) { fprintf(stderr, "%s: Cannot allocate %d bytes\n", prog, (int)(sizeof DEFAULT_EXEC_PREFIX) + strlen(label)); return EX_OSERR; } strcpy(exec, DEFAULT_EXEC_PREFIX); strcpy(exec + sizeof DEFAULT_EXEC_PREFIX - 1, label); } if (acname == NULL) { char *dot; if (gethostname(hostname, sizeof hostname)) strcpy(hostname, "localhost"); else if ((dot = strchr(hostname, '.'))) *dot = '\0'; acname = hostname; } #ifndef NOKLDLOAD if (!LoadModules()) return EX_UNAVAILABLE; #endif /* Create a socket node */ if (NgMkSockNode(NULL, &cs, &ds) == -1) { perror("Cannot create netgraph socket node"); return EX_CANTCREAT; } /* Connect it up (and fill in `ngc') */ if ((ret = ConfigureNode(prog, argv[optind], provider, cs, ds, optd, &ngc)) != 0) { close(cs); close(ds); return ret; } if (!optF && daemon(1, 0) == -1) { perror("daemon()"); close(cs); close(ds); return EX_OSERR; } if (pidfile != NULL) { FILE *fp; if ((fp = fopen(pidfile, "w")) == NULL) { perror(pidfile); close(cs); close(ds); return EX_CANTCREAT; } else { fprintf(fp, "%d\n", (int)getpid()); fclose(fp); } } openlog(prog, LOG_PID | (optF ? LOG_PERROR : 0), LOG_DAEMON); if (!optF && optn) NgSetErrLog(nglog, nglogx); memset(&act, '\0', sizeof act); act.sa_handler = Farewell; act.sa_flags = 0; sigemptyset(&act.sa_mask); sigaction(SIGHUP, &act, NULL); sigaction(SIGINT, &act, NULL); sigaction(SIGQUIT, &act, NULL); sigaction(SIGTERM, &act, NULL); while (!ReceivedSignal) { if (*provider) syslog(LOG_INFO, "Listening as provider %s", provider); else syslog(LOG_INFO, "Listening"); switch (sz = NgRecvData(ds, response, sizeof response, rhook)) { case -1: syslog(LOG_INFO, "NgRecvData: %m"); break; case 0: syslog(LOG_INFO, "NgRecvData: socket closed"); break; default: if (optd) { char *dbuf, *ptr; ptr = dbuf = alloca(sz * 2 + 1); for (f = 0; f < sz; f++, ptr += 2) sprintf(ptr, "%02x", (u_char)response[f]); *ptr = '\0'; syslog(LOG_INFO, "Got %d bytes of data: %s", sz, dbuf); } } if (sz <= 0) { ret = EX_UNAVAILABLE; break; } Spawn(prog, acname, provider, exec, ngc, cs, ds, response, sz, optd); } if (pidfile) remove(pidfile); if (ReceivedSignal) { syslog(LOG_INFO, "Received signal %d, exiting", ReceivedSignal); signal(ReceivedSignal, SIG_DFL); raise(ReceivedSignal); /* NOTREACHED */ ret = -ReceivedSignal; } return ret; }
static void Spawn(const char *prog, const char *acname, const char *provider, const char *exec, struct ngm_connect ngc, int cs, int ds, void *request, int sz, int debug) { char msgbuf[sizeof(struct ng_mesg) + sizeof(struct ngpppoe_sts)]; struct ng_mesg *rep = (struct ng_mesg *)msgbuf; struct ngpppoe_sts *sts = (struct ngpppoe_sts *)(msgbuf + sizeof *rep); struct ngpppoe_init_data *data; char env[18], unknown[14], sessionid[5], *path; unsigned char *macaddr; const char *msg; int ret, slen; switch ((ret = fork())) { case -1: syslog(LOG_ERR, "fork: %m"); break; case 0: switch (fork()) { case 0: break; case -1: _exit(errno); default: _exit(0); } close(cs); close(ds); /* Create a new socket node */ if (debug) syslog(LOG_INFO, "Creating a new socket node"); if (NgMkSockNode(NULL, &cs, &ds) == -1) { syslog(LOG_ERR, "Cannot create netgraph socket node: %m"); _exit(EX_CANTCREAT); } /* Connect the PPPoE node to our new socket node. */ snprintf(ngc.ourhook, sizeof ngc.ourhook, "exec-%ld", (long)getpid()); memcpy(ngc.peerhook, ngc.ourhook, sizeof ngc.peerhook); if (debug) syslog(LOG_INFO, "Sending CONNECT from .:%s -> %s.%s", ngc.ourhook, ngc.path, ngc.peerhook); if (NgSendMsg(cs, ".:", NGM_GENERIC_COOKIE, NGM_CONNECT, &ngc, sizeof ngc) < 0) { syslog(LOG_ERR, "Cannot CONNECT PPPoE and socket nodes: %m"); _exit(EX_OSERR); } /* * If we tell the socket node not to LINGER, it will go away when * the last hook is removed. */ if (debug) syslog(LOG_INFO, "Sending NGM_SOCK_CMD_NOLINGER to socket"); if (NgSendMsg(cs, ".:", NGM_SOCKET_COOKIE, NGM_SOCK_CMD_NOLINGER, NULL, 0) < 0) { syslog(LOG_ERR, "Cannot send NGM_SOCK_CMD_NOLINGER: %m"); _exit(EX_OSERR); } /* Put the PPPoE node into OFFER mode */ slen = strlen(acname); data = (struct ngpppoe_init_data *)alloca(sizeof *data + slen); snprintf(data->hook, sizeof data->hook, "%s", ngc.ourhook); memcpy(data->data, acname, slen); data->data_len = slen; path = (char *)alloca(strlen(ngc.ourhook) + 3); strcpy(path, ".:"); strcpy(path + 2, ngc.ourhook); syslog(LOG_INFO, "Offering to %s as access concentrator %s", path, acname); if (NgSendMsg(cs, path, NGM_PPPOE_COOKIE, NGM_PPPOE_OFFER, data, sizeof *data + slen) == -1) { syslog(LOG_INFO, "%s: Cannot OFFER on netgraph node: %m", path); _exit(EX_OSERR); } /* If we have a provider code, set it */ if (provider) { slen = strlen(provider); data = (struct ngpppoe_init_data *)alloca(sizeof *data + slen); snprintf(data->hook, sizeof data->hook, "%s", ngc.ourhook); memcpy(data->data, provider, slen); data->data_len = slen; syslog(LOG_INFO, "adding to %s as offered service %s", path, acname); if (NgSendMsg(cs, path, NGM_PPPOE_COOKIE, NGM_PPPOE_SERVICE, data, sizeof *data + slen) == -1) { syslog(LOG_INFO, "%s: Cannot add service on netgraph node: %m", path); _exit(EX_OSERR); } } /* Put the peer's MAC address in the environment */ if (sz >= sizeof(struct ether_header)) { macaddr = ((struct ether_header *)request)->ether_shost; snprintf(env, sizeof(env), "%x:%x:%x:%x:%x:%x", macaddr[0], macaddr[1], macaddr[2], macaddr[3], macaddr[4], macaddr[5]); if (setenv(HISMACADDR, env, 1) != 0) syslog(LOG_INFO, "setenv: cannot set %s: %m", HISMACADDR); } /* And send our request data to the waiting node */ if (debug) syslog(LOG_INFO, "Sending original request to %s (%d bytes)", path, sz); if (NgSendData(ds, ngc.ourhook, request, sz) == -1) { syslog(LOG_ERR, "Cannot send original request to %s: %m", path); _exit(EX_OSERR); } /* Then wait for a success indication */ if (debug) syslog(LOG_INFO, "Waiting for a SUCCESS reply %s", path); do { if ((ret = NgRecvMsg(cs, rep, sizeof msgbuf, NULL)) < 0) { syslog(LOG_ERR, "%s: Cannot receive a message: %m", path); _exit(EX_OSERR); } if (ret == 0) { /* The socket has been closed */ syslog(LOG_INFO, "%s: Client timed out", path); _exit(EX_TEMPFAIL); } if (rep->header.version != NG_VERSION) { syslog(LOG_ERR, "%ld: Unexpected netgraph version, expected %ld", (long)rep->header.version, (long)NG_VERSION); _exit(EX_PROTOCOL); } if (rep->header.typecookie != NGM_PPPOE_COOKIE) { syslog(LOG_INFO, "%ld: Unexpected netgraph cookie, expected %ld", (long)rep->header.typecookie, (long)NGM_PPPOE_COOKIE); continue; } switch (rep->header.cmd) { case NGM_PPPOE_SET_FLAG: msg = "SET_FLAG"; break; case NGM_PPPOE_CONNECT: msg = "CONNECT"; break; case NGM_PPPOE_LISTEN: msg = "LISTEN"; break; case NGM_PPPOE_OFFER: msg = "OFFER"; break; case NGM_PPPOE_SUCCESS: msg = "SUCCESS"; break; case NGM_PPPOE_FAIL: msg = "FAIL"; break; case NGM_PPPOE_CLOSE: msg = "CLOSE"; break; case NGM_PPPOE_GET_STATUS: msg = "GET_STATUS"; break; case NGM_PPPOE_ACNAME: msg = "ACNAME"; if (setenv("ACNAME", sts->hook, 1) != 0) syslog(LOG_WARNING, "setenv: cannot set ACNAME=%s: %m", sts->hook); break; case NGM_PPPOE_SESSIONID: msg = "SESSIONID"; snprintf(sessionid, sizeof sessionid, "%04x", *(u_int16_t *)sts); if (setenv("SESSIONID", sessionid, 1) != 0) syslog(LOG_WARNING, "setenv: cannot set SESSIONID=%s: %m", sessionid); break; default: snprintf(unknown, sizeof unknown, "<%d>", (int)rep->header.cmd); msg = unknown; break; } switch (rep->header.cmd) { case NGM_PPPOE_FAIL: case NGM_PPPOE_CLOSE: syslog(LOG_ERR, "Received NGM_PPPOE_%s (hook \"%s\")", msg, sts->hook); _exit(0); } syslog(LOG_INFO, "Received NGM_PPPOE_%s (hook \"%s\")", msg, sts->hook); } while (rep->header.cmd != NGM_PPPOE_SUCCESS); dup2(ds, STDIN_FILENO); dup2(ds, STDOUT_FILENO); close(ds); close(cs); setsid(); syslog(LOG_INFO, "Executing: %s", exec); execlp(_PATH_BSHELL, _PATH_BSHELL, "-c", exec, (char *)NULL); syslog(LOG_ERR, "execlp failed: %m"); _exit(EX_OSFILE); default: wait(&ret); errno = ret; if (errno) syslog(LOG_ERR, "Second fork failed: %m"); break; } }
/* * 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); }
int main(int argc, char **argv) { int c; char sname[16]; char *ng_name; char *rflags = "0", *rfname = NULL, *wfname = NULL; fl_use_in = fl_use_out = 1; /* parse options */ while ((c = getopt(argc, argv, "T:d:f:inor:w:")) != -1) { switch (c) { case 'T': /* set socket ready timeout, in secs. */ read_to = atoi(optarg); break; case 'd': /* set libnetgraph debug level. */ NgSetDebug(atoi(optarg)); break; case 'f': /* flags for -r switch */ rflags = optarg; break; case 'i': /* use only input hook */ fl_use_in = 1; fl_use_out = 0; break; case 'n': fl_ipnum = 1; break; case 'o': /* use only output hook */ fl_use_out = 1; fl_use_in = 0; break; case 'r': /* get data from file, not from node */ fl_rfile = 1; rfname = optarg; break; case 'w': /* write data in binary to file */ wfname = optarg; break; } } if (fl_rfile) { ip_account_read(rfname, rflags); exit(0); } if (wfname != NULL) { wfp = fopen(wfname, "a"); if (wfp == NULL) err(1, "fopen"); } argc -= optind; argv += optind; ng_name = argv[0]; if (ng_name == NULL) help(); argc --; argv ++; if((ng_hookprefix = strchr(ng_name, ':'))) *(ng_hookprefix++) = '\0'; else ng_hookprefix = ng_nodename; snprintf(ng_nodename, sizeof(ng_nodename), "%s:", ng_name); /* creat control socket. */ snprintf(sname, sizeof(sname), "ipacct%i", getpid()); if (NgMkSockNode(sname, &ng_cs, NULL) == -1) err(1, "NgMkSockNode"); #if 0 /* set control socket nonblocking */ if ((flags = fcntl(ng_cs, F_GETFL, 0)) == -1) err(1, "fcntl(F_GETFL)"); flags |= O_NONBLOCK; if (fcntl(ng_cs, F_SETFL, flags) == -1) err(1, "fcntl(F_SETFL)"); /* * XXX we don't set receive buffer size 'cause * reply size (NG control message + accounting * chunk) is smaller than default buffer size. * But this is sometimes can be not true. */ /* set receive buffer size */ if (setsockopt(ng_cs, SOL_SOCKET, SO_RCVBUF, &rcvbuf, sizeof(int)) == -1) err(1, "setsockopt(SOL_SOCKET, SO_RCVBUF)"); #endif /* check versions */ g_vinfo = check_version(); /* parse and execute command */ execute_command(argc, argv); close(ng_cs); exit(0); }
/* * main() */ int main(int ac, char *av[]) { struct ngm_connect ngc; const char *path = NULL; const char *hook = DEFAULT_HOOKNAME; int csock, dsock; int asciiFlag = 0; int loopFlag = 0; int noInput = 0; int execFlag = 0; int ch; if ((msgs = sl_init()) == NULL) err(EX_OSERR, NULL); /* Parse flags */ while ((ch = getopt(ac, av, "aedlm:nsS")) != -1) { switch (ch) { case 'a': asciiFlag = 1; break; case 'd': NgSetDebug(NgSetDebug(-1) + 1); break; case 'e': execFlag = 1; break; case 'l': loopFlag = 1; break; case 'n': noInput = 1; break; case 'm': if (sl_add(msgs, optarg) == -1) err(EX_OSERR, NULL); break; case 's': outfd = STDIN_FILENO; break; case 'S': infd = STDOUT_FILENO; break; case '?': default: Usage(); } } ac -= optind; av += optind; if (execFlag) { if (asciiFlag || loopFlag) { fprintf(stderr, "conflicting options\n"); Usage(); } if (ac < 3) Usage(); path = av[0]; hook = av[1]; av += 2; ac -= 2; } else { /* Get params */ switch (ac) { case 2: hook = av[1]; /* FALLTHROUGH */ case 1: path = av[0]; break; default: Usage(); } } /* Get sockets */ if (NgMkSockNode(NULL, &csock, &dsock) < 0) errx(EX_OSERR, "can't get sockets"); /* Connect socket node to specified node */ snprintf(ngc.path, sizeof(ngc.path), "%s", path); snprintf(ngc.ourhook, sizeof(ngc.ourhook), NG_SOCK_HOOK_NAME); snprintf(ngc.peerhook, sizeof(ngc.peerhook), "%s", hook); if (NgSendMsg(csock, ".", NGM_GENERIC_COOKIE, NGM_CONNECT, &ngc, sizeof(ngc)) < 0) errx(EX_OSERR, "can't connect to node"); if (execFlag) { /* move dsock to fd 0 and 1 */ (void)close(0); (void)close(1); if (!noInput) (void)dup2(dsock, 0); (void)dup2(dsock, 1); send_msgs(csock, path); /* try executing the program */ (void)execv(av[0], av); err(EX_OSERR, "%s", av[0]); } else send_msgs(csock, path); /* Close standard input if not reading from it */ if (noInput) fclose(stdin); /* Relay data */ while (1) { fd_set rfds; /* Setup bits */ FD_ZERO(&rfds); if (!noInput) FD_SET(infd, &rfds); FD_SET(dsock, &rfds); /* Wait for something to happen */ if (select(FD_SETSIZE, &rfds, NULL, NULL, NULL) < 0) err(EX_OSERR, "select"); /* Check data from socket */ if (FD_ISSET(dsock, &rfds)) { char buf[BUF_SIZE]; int rl, wl; /* Read packet from socket */ if ((rl = NgRecvData(dsock, buf, sizeof(buf), NULL)) < 0) err(EX_OSERR, "read(hook)"); if (rl == 0) errx(EX_OSERR, "read EOF from hook?!"); /* Write packet to stdout */ if (asciiFlag) WriteAscii((u_char *) buf, rl); else if ((wl = write(outfd, buf, rl)) != rl) { if (wl < 0) { err(EX_OSERR, "write(stdout)"); } else { errx(EX_OSERR, "stdout: read %d, wrote %d", rl, wl); } } /* Loopback */ if (loopFlag) { if (NgSendData(dsock, NG_SOCK_HOOK_NAME, buf, rl) < 0) err(EX_OSERR, "write(hook)"); } } /* Check data from stdin */ if (FD_ISSET(infd, &rfds)) { char buf[BUF_SIZE]; int rl; /* Read packet from stdin */ if ((rl = read(infd, buf, sizeof(buf))) < 0) err(EX_OSERR, "read(stdin)"); if (rl == 0) errx(EX_OSERR, "EOF(stdin)"); /* Write packet to socket */ if (NgSendData(dsock, NG_SOCK_HOOK_NAME, buf, rl) < 0) err(EX_OSERR, "write(hook)"); } } }