static ssize_t ether_Read(struct physical *p, void *v, size_t n) { char hook[sizeof TUN_NAME + 11]; return NgRecvData(p->fd, v, n, hook); }
/* * Identical to NgRecvData() except buffer is dynamically allocated. */ int NgAllocRecvData(int ds, u_char **buf, char *hook) { int len; socklen_t optlen; optlen = sizeof(len); if (getsockopt(ds, SOL_SOCKET, SO_RCVBUF, &len, &optlen) == -1 || (*buf = malloc(len)) == NULL) return (-1); if ((len = NgRecvData(ds, *buf, len, hook)) < 0) free(*buf); return (len); }
static ssize_t ng_Read(struct physical *p, void *v, size_t n) { char hook[NG_HOOKSIZ]; log_Printf(LogDEBUG, "ng_Read\n"); switch (p->dl->state) { case DATALINK_DIAL: case DATALINK_LOGIN: return ng_MessageIn(p, v, n); } return NgRecvData(p->fd, v, n, hook); }
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; }
/* * 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)"); } } }