Пример #1
0
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);
}
Пример #2
0
/*
 * 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);
}
Пример #3
0
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);
}
Пример #4
0
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;
}
Пример #5
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)");
		}
	}
}