Exemplo n.º 1
0
int
rcmd_af(char **ahost, int rport, const char *locuser, const char *remuser,
	const char *cmd, int *fd2p, int af)
{
	struct addrinfo hints, *res, *ai;
	struct sockaddr_storage from;
	fd_set reads;
	sigset_t oldmask, newmask;
	pid_t pid;
	int s, aport, lport, timo, error;
	char c, *p;
	int refused, nres;
	char num[8];
	static char canonnamebuf[MAXDNAME];	/* is it proper here? */

	/* call rcmdsh() with specified remote shell if appropriate. */
	if (!issetugid() && (p = getenv("RSH"))) {
		struct servent *sp = getservbyname("shell", "tcp");

		if (sp && sp->s_port == rport)
			return (rcmdsh(ahost, rport, locuser, remuser,
			    cmd, p));
	}

	/* use rsh(1) if non-root and remote port is shell. */
	if (geteuid()) {
		struct servent *sp = getservbyname("shell", "tcp");

		if (sp && sp->s_port == rport)
			return (rcmdsh(ahost, rport, locuser, remuser,
			    cmd, NULL));
	}

	pid = getpid();

	memset(&hints, 0, sizeof(hints));
	hints.ai_flags = AI_CANONNAME;
	hints.ai_family = af;
	hints.ai_socktype = SOCK_STREAM;
	hints.ai_protocol = 0;
	snprintf(num, sizeof(num), "%d", ntohs(rport));
	error = getaddrinfo(*ahost, num, &hints, &res);
	if (error) {
		fprintf(stderr, "rcmd: getaddrinfo: %s\n",
			gai_strerror(error));
		if (error == EAI_SYSTEM)
			fprintf(stderr, "rcmd: getaddrinfo: %s\n",
				strerror(errno));
		return (-1);
	}

	if (res->ai_canonname &&
	    strlen(res->ai_canonname) + 1 < sizeof(canonnamebuf)) {
		strncpy(canonnamebuf, res->ai_canonname, sizeof(canonnamebuf));
		*ahost = canonnamebuf;
	}
	nres = 0;
	for (ai = res; ai; ai = ai->ai_next)
		nres++;
	ai = res;
	refused = 0;
	sigemptyset(&newmask);
	sigaddset(&newmask, SIGURG);
	_sigprocmask(SIG_BLOCK, (const sigset_t *)&newmask, &oldmask);
	for (timo = 1, lport = IPPORT_RESERVED - 1;;) {
		s = rresvport_af(&lport, ai->ai_family);
		if (s < 0) {
			if (errno != EAGAIN && ai->ai_next) {
				ai = ai->ai_next;
				continue;
			}
			if (errno == EAGAIN)
				fprintf(stderr,
				    "rcmd: socket: All ports in use\n");
			else
				fprintf(stderr, "rcmd: socket: %s\n",
				    strerror(errno));
			freeaddrinfo(res);
			_sigprocmask(SIG_SETMASK, (const sigset_t *)&oldmask,
			    NULL);
			return (-1);
		}
		_fcntl(s, F_SETOWN, pid);
		if (_connect(s, ai->ai_addr, ai->ai_addrlen) >= 0)
			break;
		_close(s);
		if (errno == EADDRINUSE) {
			lport--;
			continue;
		}
		if (errno == ECONNREFUSED)
			refused = 1;
		if (ai->ai_next == NULL && (!refused || timo > 16)) {
			fprintf(stderr, "%s: %s\n", *ahost, strerror(errno));
			freeaddrinfo(res);
			_sigprocmask(SIG_SETMASK, (const sigset_t *)&oldmask,
			    NULL);
			return (-1);
		}
		if (nres > 1) {
			int oerrno = errno;

			getnameinfo(ai->ai_addr, ai->ai_addrlen, paddr,
			    sizeof(paddr), NULL, 0, NI_NUMERICHOST);
			fprintf(stderr, "connect to address %s: ", paddr);
			errno = oerrno;
			perror(0);
		}
		if ((ai = ai->ai_next) == NULL) {
			/* refused && timo <= 16 */
			struct timespec time_to_sleep, time_remaining;

			time_to_sleep.tv_sec = timo;
			time_to_sleep.tv_nsec = 0;
			_nanosleep(&time_to_sleep, &time_remaining);
			timo *= 2;
			ai = res;
			refused = 0;
		}
		if (nres > 1) {
			getnameinfo(ai->ai_addr, ai->ai_addrlen, paddr,
			    sizeof(paddr), NULL, 0, NI_NUMERICHOST);
			fprintf(stderr, "Trying %s...\n", paddr);
		}
	}
	lport--;
	if (fd2p == 0) {
		_write(s, "", 1);
		lport = 0;
	} else {
		int s2 = rresvport_af(&lport, ai->ai_family), s3;
		socklen_t len = ai->ai_addrlen;
		int nfds;

		if (s2 < 0)
			goto bad;
		_listen(s2, 1);
		snprintf(num, sizeof(num), "%d", lport);
		if (_write(s, num, strlen(num)+1) != strlen(num)+1) {
			fprintf(stderr,
			    "rcmd: write (setting up stderr): %s\n",
			    strerror(errno));
			_close(s2);
			goto bad;
		}
		nfds = max(s, s2)+1;
		if(nfds > FD_SETSIZE) {
			fprintf(stderr, "rcmd: too many files\n");
			_close(s2);
			goto bad;
		}
again:
		FD_ZERO(&reads);
		FD_SET(s, &reads);
		FD_SET(s2, &reads);
		errno = 0;
		if (_select(nfds, &reads, 0, 0, 0) < 1 || !FD_ISSET(s2, &reads)){
			if (errno != 0)
				fprintf(stderr,
				    "rcmd: select (setting up stderr): %s\n",
				    strerror(errno));
			else
				fprintf(stderr,
				"select: protocol failure in circuit setup\n");
			_close(s2);
			goto bad;
		}
		s3 = _accept(s2, (struct sockaddr *)&from, &len);
		switch (from.ss_family) {
		case AF_INET:
			aport = ntohs(((struct sockaddr_in *)&from)->sin_port);
			break;
#ifdef INET6
		case AF_INET6:
			aport = ntohs(((struct sockaddr_in6 *)&from)->sin6_port);
			break;
#endif
		default:
			aport = 0;	/* error */
			break;
		}
		/*
		 * XXX careful for ftp bounce attacks. If discovered, shut them
		 * down and check for the real auxiliary channel to connect.
		 */
		if (aport == 20) {
			_close(s3);
			goto again;
		}
		_close(s2);
		if (s3 < 0) {
			fprintf(stderr,
			    "rcmd: accept: %s\n", strerror(errno));
			lport = 0;
			goto bad;
		}
		*fd2p = s3;
		if (aport >= IPPORT_RESERVED || aport < IPPORT_RESERVED / 2) {
			fprintf(stderr,
			    "socket: protocol failure in circuit setup.\n");
			goto bad2;
		}
	}
	_write(s, locuser, strlen(locuser)+1);
	_write(s, remuser, strlen(remuser)+1);
	_write(s, cmd, strlen(cmd)+1);
	if (_read(s, &c, 1) != 1) {
		fprintf(stderr,
		    "rcmd: %s: %s\n", *ahost, strerror(errno));
		goto bad2;
	}
	if (c != 0) {
		while (_read(s, &c, 1) == 1) {
			_write(STDERR_FILENO, &c, 1);
			if (c == '\n')
				break;
		}
		goto bad2;
	}
	_sigprocmask(SIG_SETMASK, (const sigset_t *)&oldmask, NULL);
	freeaddrinfo(res);
	return (s);
bad2:
	if (lport)
		_close(*fd2p);
bad:
	_close(s);
	_sigprocmask(SIG_SETMASK, (const sigset_t *)&oldmask, NULL);
	freeaddrinfo(res);
	return (-1);
}
Exemplo n.º 2
0
Arquivo: pop.c Projeto: RyanKung/emacs
/*
 * Function: socket_connection
 *
 * Purpose: Opens the network connection with the mail host, without
 * 	doing any sort of I/O with it or anything.
 *
 * Arguments:
 * 	host	The host to which to connect.
 *	flags	Option flags.
 *
 * Return value: A file descriptor indicating the connection, or -1
 * 	indicating failure, in which case an error has been copied
 * 	into pop_error.
 */
static int
socket_connection (char *host, int flags)
{
#ifdef HAVE_GETADDRINFO
  struct addrinfo *res, *it;
  struct addrinfo hints;
  int ret;
#else /* !HAVE_GETADDRINFO */
  struct hostent *hostent;
#endif
  struct servent *servent;
  struct sockaddr_in addr;
  char found_port = 0;
  const char *service;
  int sock;
  char *realhost;
#ifdef KERBEROS
#ifdef KERBEROS5
  krb5_error_code rem;
  krb5_context kcontext = 0;
  krb5_auth_context auth_context = 0;
  krb5_ccache ccdef;
  krb5_principal client, server;
  krb5_error *err_ret;
  register char *cp;
#else
  KTEXT ticket;
  MSG_DAT msg_data;
  CREDENTIALS cred;
  Key_schedule schedule;
  int rem;
#endif /* KERBEROS5 */
#endif /* KERBEROS */

  int try_count = 0;
  int connect_ok;

#ifdef WINDOWSNT
  {
    WSADATA winsockData;
    if (WSAStartup (0x101, &winsockData) == 0)
      have_winsock = 1;
  }
#endif

  memset (&addr, 0, sizeof (addr));
  addr.sin_family = AF_INET;

  /** "kpop" service is  never used: look for 20060515 to see why **/
#ifdef KERBEROS
  service = (flags & POP_NO_KERBEROS) ? POP_SERVICE : KPOP_SERVICE;
#else
  service = POP_SERVICE;
#endif

#ifdef HESIOD
  if (! (flags & POP_NO_HESIOD))
    {
      servent = hes_getservbyname (service, "tcp");
      if (servent)
	{
	  addr.sin_port = servent->s_port;
	  found_port = 1;
	}
    }
#endif
  if (! found_port)
    {
      servent = getservbyname (service, "tcp");
      if (servent)
	{
	  addr.sin_port = servent->s_port;
	}
      else
	{
  /** "kpop" service is  never used: look for 20060515 to see why **/
#ifdef KERBEROS
	  addr.sin_port = htons ((flags & POP_NO_KERBEROS) ?
				POP_PORT : KPOP_PORT);
#else
	  addr.sin_port = htons (POP_PORT);
#endif
	}
    }

#define POP_SOCKET_ERROR "Could not create socket for POP connection: "

  sock = socket (PF_INET, SOCK_STREAM, 0);
  if (sock < 0)
    {
      snprintf (pop_error, ERROR_MAX, "%s%s",
		POP_SOCKET_ERROR, strerror (errno));
      return (-1);

    }

#ifdef HAVE_GETADDRINFO
  memset (&hints, 0, sizeof (hints));
  hints.ai_socktype = SOCK_STREAM;
  hints.ai_flags = AI_CANONNAME;
  hints.ai_family = AF_INET;
  do
    {
      ret = getaddrinfo (host, service, &hints, &res);
      try_count++;
      if (ret != 0 && (ret != EAI_AGAIN || try_count == 5))
	{
	  strcpy (pop_error, "Could not determine POP server's address");
	  return (-1);
	}
    } while (ret != 0);

  if (ret == 0)
    {
      it = res;
      while (it)
        {
          if (it->ai_addrlen == sizeof (addr))
            {
              struct sockaddr_in *in_a = (struct sockaddr_in *) it->ai_addr;
              memcpy (&addr.sin_addr, &in_a->sin_addr, sizeof (addr.sin_addr));
              if (! connect (sock, (struct sockaddr *) &addr, sizeof (addr)))
                break;
            }
          it = it->ai_next;
        }
      connect_ok = it != NULL;
      if (connect_ok)
        {
          realhost = alloca (strlen (it->ai_canonname) + 1);
          strcpy (realhost, it->ai_canonname);
        }
      freeaddrinfo (res);
    }
#else /* !HAVE_GETADDRINFO */
  do
    {
      hostent = gethostbyname (host);
      try_count++;
      if ((! hostent) && ((h_errno != TRY_AGAIN) || (try_count == 5)))
	{
	  strcpy (pop_error, "Could not determine POP server's address");
	  return (-1);
	}
    } while (! hostent);

  while (*hostent->h_addr_list)
    {
      memcpy (&addr.sin_addr, *hostent->h_addr_list, hostent->h_length);
      if (! connect (sock, (struct sockaddr *) &addr, sizeof (addr)))
	break;
      hostent->h_addr_list++;
    }
  connect_ok = *hostent->h_addr_list != NULL;
  if (! connect_ok)
    {
      realhost = alloca (strlen (hostent->h_name) + 1);
      strcpy (realhost, hostent->h_name);
    }

#endif /* !HAVE_GETADDRINFO */

#define CONNECT_ERROR "Could not connect to POP server: "

  if (! connect_ok)
    {
      CLOSESOCKET (sock);
      snprintf (pop_error, ERROR_MAX, "%s%s", CONNECT_ERROR, strerror (errno));
      return (-1);

    }

#ifdef KERBEROS

#define KRB_ERROR "Kerberos error connecting to POP server: "
  if (! (flags & POP_NO_KERBEROS))
    {
#ifdef KERBEROS5
      if ((rem = krb5_init_context (&kcontext)))
	{
	krb5error:
	  if (auth_context)
	    krb5_auth_con_free (kcontext, auth_context);
	  if (kcontext)
	    krb5_free_context (kcontext);
	  snprintf (pop_error, ERROR_MAX, "%s%s",
		    KRB_ERROR, error_message (rem));
	  CLOSESOCKET (sock);
	  return (-1);
	}

      if ((rem = krb5_auth_con_init (kcontext, &auth_context)))
	goto krb5error;

      if (rem = krb5_cc_default (kcontext, &ccdef))
	goto krb5error;

      if (rem = krb5_cc_get_principal (kcontext, ccdef, &client))
	goto krb5error;

      for (cp = realhost; *cp; cp++)
	{
	  if (isupper (*cp))
	    {
	      *cp = tolower (*cp);
	    }
	}

      if (rem = krb5_sname_to_principal (kcontext, realhost,
					 POP_SERVICE, FALSE, &server))
	goto krb5error;

      rem = krb5_sendauth (kcontext, &auth_context,
			   (krb5_pointer) &sock, "KPOPV1.0", client, server,
			  AP_OPTS_MUTUAL_REQUIRED,
			  0,	/* no checksum */
			  0,	/* no creds, use ccache instead */
			  ccdef,
			  &err_ret,
			  0,	/* don't need subsession key */
			  0);	/* don't need reply */
      krb5_free_principal (kcontext, server);
      if (rem)
	{
	  int pop_error_len = snprintf (pop_error, ERROR_MAX, "%s%s",
					KRB_ERROR, error_message (rem));
#if defined HAVE_KRB5_ERROR_TEXT
	  if (err_ret && err_ret->text.length)
	    {
	      int errlen = err_ret->text.length;
	      snprintf (pop_error + pop_error_len, ERROR_MAX - pop_error_len,
			" [server says '.*%s']", errlen, err_ret->text.data);
	    }
#elif defined HAVE_KRB5_ERROR_E_TEXT
	  if (err_ret && err_ret->e_text && **err_ret->e_text)
	    snprintf (pop_error + pop_error_len, ERRMAX - pop_error_len,
		      " [server says '%s']", *err_ret->e_text);
#endif
	  if (err_ret)
	    krb5_free_error (kcontext, err_ret);
	  krb5_auth_con_free (kcontext, auth_context);
	  krb5_free_context (kcontext);

	  CLOSESOCKET (sock);
	  return (-1);
	}
#else  /* ! KERBEROS5 */
      ticket = (KTEXT) malloc (sizeof (KTEXT_ST));
      rem = krb_sendauth (0L, sock, ticket, "pop", realhost,
			  (char *) krb_realmofhost (realhost),
			  (unsigned long) 0, &msg_data, &cred, schedule,
			  (struct sockaddr_in *) 0,
			  (struct sockaddr_in *) 0,
			  "KPOPV0.1");
      free ((char *) ticket);
      if (rem != KSUCCESS)
	{
	  snprintf (pop_error, ERROR_MAX, "%s%s", KRB_ERROR, krb_err_txt[rem]);
	  CLOSESOCKET (sock);
	  return (-1);
	}
#endif /* KERBEROS5 */
    }
#endif /* KERBEROS */

  return (sock);
} /* socket_connection */
Exemplo n.º 3
0
int
main(int argc, char *argv[])
{
	size_t blc, bls, black, white;
	char *db_array[2], *buf, *name;
	struct blacklist *blists;
	struct servent *ent;
	int daemonize = 0, ch;

	while ((ch = getopt(argc, argv, "bdDn")) != -1) {
		switch (ch) {
		case 'n':
			dryrun = 1;
			break;
		case 'd':
			debug = 1;
			break;
		case 'b':
			greyonly = 0;
			break;
		case 'D':
			daemonize = 1;
			break;
		default:
			usage();
			break;
		}
	}
	argc -= optind;
	argv += optind;
	if (argc != 0)
		usage();

	if (daemonize)
		daemon(0, 0);

	if ((ent = getservbyname("spamd-cfg", "tcp")) == NULL)
		errx(1, "cannot find service \"spamd-cfg\" in /etc/services");
	ent->s_port = ntohs(ent->s_port);

	db_array[0] = PATH_SPAMD_CONF;
	db_array[1] = NULL;

	if (cgetent(&buf, db_array, "all") != 0)
		err(1, "Can't find \"all\" in spamd config");
	name = strsep(&buf, ": \t"); /* skip "all" at start */
	blists = NULL;
	blc = bls = 0;
	while ((name = strsep(&buf, ": \t")) != NULL) {
		if (*name) {
			/* extract config in order specified in "all" tag */
			if (blc == bls) {
				struct blacklist *tmp;

				bls += 32;
				tmp = realloc(blists,
				    bls * sizeof(struct blacklist));
				if (tmp == NULL)
					errx(1, "malloc failed");
				blists = tmp;
			}
			if (blc == 0)
				black = white = 0;
			else {
				white = blc - 1;
				black = blc;
			}
			memset(&blists[black], 0, sizeof(struct blacklist));
			black = getlist(db_array, name, &blists[white],
			    &blists[black]);
			if (black && blc > 0) {
				/* collapse and free previous blacklist */
				send_blacklist(&blists[blc - 1], ent->s_port);
			}
			blc += black;
		}
	}
	/* collapse and free last blacklist */
	if (blc > 0)
		send_blacklist(&blists[blc - 1], ent->s_port);
	return (0);
}
Exemplo n.º 4
0
int
server_mode (const char *pidfile, struct sockaddr_in *phis_addr)
{
  int ctl_sock, fd;
  struct servent *sv;
  int port;
  static struct  sockaddr_in server_addr;  /* Our address.  */

  /* Become a daemon.  */
#ifdef HAVE_DAEMON
  if (daemon(1,1) < 0)
#endif
    {
      syslog (LOG_ERR, "failed to become a daemon");
      return -1;
    }
  (void) signal (SIGCHLD, reapchild);

  /* Get port for ftp/tcp.  */
  sv = getservbyname ("ftp", "tcp");
  port = (sv == NULL) ? DEFPORT : sv->s_port;

  /* Open socket, bind and start listen.  */
  ctl_sock = socket (AF_INET, SOCK_STREAM, 0);
  if (ctl_sock < 0)
    {
      syslog (LOG_ERR, "control socket: %m");
      return -1;
    }

  /* Enable local address reuse.  */
  {
    int on = 1;
    if (setsockopt (ctl_sock, SOL_SOCKET, SO_REUSEADDR,
		    (char *)&on, sizeof(on)) < 0)
      syslog (LOG_ERR, "control setsockopt: %m");
  }

  memset (&server_addr, 0, sizeof server_addr);
  server_addr.sin_family = AF_INET;
  server_addr.sin_port = htons (port);

  if (bind (ctl_sock, (struct sockaddr *)&server_addr, sizeof server_addr))
    {
      syslog (LOG_ERR, "control bind: %m");
      return -1;
    }
  if (listen (ctl_sock, 32) < 0)
    {
      syslog (LOG_ERR, "control listen: %m");
      return -1;
    }

  /* Stash pid in pidfile.  */
  {
    FILE *pid_fp = fopen (pidfile, "w");
    if (pid_fp == NULL)
      syslog (LOG_ERR, "can't open %s: %m", PATH_FTPDPID);
    else
      {
	fprintf (pid_fp, "%d\n", getpid());
	fchmod (fileno(pid_fp), S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH);
	fclose (pid_fp);
      }
  }

  /* Loop forever accepting connection requests and forking off
     children to handle them.  */
  while (1)
    {
      int addrlen = sizeof (*phis_addr);
      fd = accept (ctl_sock, (struct sockaddr *)phis_addr, &addrlen);
#ifdef HAVE_WORKING_FORK
      if (fork () == 0) /* child */
#else
      if (vfork () == 0) /* child */
#endif
	{
	  (void) dup2 (fd, 0);
	  (void) dup2 (fd, 1);
	  close (ctl_sock);
	  break;
	}
      close (fd);
    }

#ifdef WITH_WRAP
  /* In the child.  */
  if (!check_host ((struct sockaddr *)phis_addr))
    return -1;
#endif
  return fd;
}
Exemplo n.º 5
0
int main(int argc, const char *argv[])
{
	struct sockaddr_in si;
	socklen_t socklen;
	struct servent *s;
	int sockfd, i;

	signal(SIGCHLD, SIG_IGN);

	printf("ftps v1.0\n");
	printf("2015.03.29\n");
	printf("author niulibing\n");

	if((fp=fopen("/etc/ftp.conf", "r")) == NULL)
	{
		perror("fopen");
		exit(1);
	}

	fgets(data, sizeof(data), fp);
	data[strlen(data)-1] = '\0';
	chdir(data);

	if((sockfd=socket(AF_INET, SOCK_STREAM, 0)) == -1)
	{
		perror("socket");
		exit(1);
	}

	if((s=getservbyname("ftp", "tcp")) == NULL)
	{
		printf("getservbyname fail\n");
		exit(1);
	}

	si.sin_family = AF_INET;
	si.sin_port = s->s_port;
	si.sin_addr.s_addr = INADDR_ANY;
	if(bind(sockfd, (const struct sockaddr *)&si, sizeof(si)) == -1)
	{
		perror("bind");
		exit(1);
	}

	if(listen(sockfd, 5) == -1)
	{
		perror("listen");
		exit(1);
	}

	while(1)
	{
		socklen = sizeof(si);
		if((acceptfd=accept(sockfd, (struct sockaddr *)&si, &socklen)) == -1)
		{
			perror("accept");
			exit(1);
		}

		if(fork() == 0)
		{
			close(sockfd);
			
			while(recv(acceptfd, data, sizeof(data), 0) > 0)
			{
				arg[0] = strtok(data, " ");
				for(i=1; arg[i-1]!=NULL; i++)
				{
					arg[i] = strtok(NULL, " ");
				}

				if(strcmp(arg[0], "list") == 0)
				{
					list();
					break;
				}

				if(strcmp(arg[0], "get") == 0)
				{
					get();
					break;
				}

				if(strcmp(arg[0], "put") == 0)
				{
					put();
					break;
				}
			}

			close(acceptfd);
			exit(0);
		}

		close(acceptfd);
	}
}
Exemplo n.º 6
0
/*
 * FtpConnect - connect to remote server
 *
 * return 1 if connected, 0 if not
 */
GLOBALDEF int FtpConnect(const char *host, netbuf **nControl)
{
    int sControl;
    struct sockaddr_in sin;
    struct hostent *phe;
    struct servent *pse;
    int on=1;
    netbuf *ctrl;
    char *lhost;
    char *pnum;

    memset(&sin,0,sizeof(sin));
    sin.sin_family = AF_INET;
    lhost = _strdup(host);
    pnum = strchr(lhost,':');
    if (pnum == NULL)
    {
#if defined(VMS)
    	sin.sin_port = htons(21);
#else
    	if ((pse = getservbyname("ftp","tcp")) == NULL)
    	{
	    perror("getservbyname");
	    return 0;
    	}
    	sin.sin_port = pse->s_port;
#endif
    }
    else
    {
	*pnum++ = '\0';
	if (isdigit(*pnum))
	    sin.sin_port = htons((short)atoi(pnum));
	else
	{
	    pse = getservbyname(pnum,"tcp");
	    sin.sin_port = pse->s_port;
	}
    }
    if ((sin.sin_addr.s_addr = inet_addr(lhost)) == -1)
    {
    	if ((phe = gethostbyname(lhost)) == NULL)
    	{
	    perror("gethostbyname");
	    return 0;
    	}
    	memcpy((char *)&sin.sin_addr, phe->h_addr, phe->h_length);
    }
    free(lhost);
    sControl = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
    if (sControl == -1)
    {
	perror("socket");
	return 0;
    }
    if (setsockopt(sControl,SOL_SOCKET,SO_REUSEADDR,
		   SETSOCKOPT_OPTVAL_TYPE &on, sizeof(on)) == -1)
    {
	perror("setsockopt");
	net_close(sControl);
	return 0;
    }
    if (connect(sControl, (struct sockaddr *)&sin, sizeof(sin)) == -1)
    {
	perror("connect");
	net_close(sControl);
	return 0;
    }
    ctrl = calloc(1,sizeof(netbuf));
    if (ctrl == NULL)
    {
	perror("calloc");
	net_close(sControl);
	return 0;
    }
    ctrl->buf = malloc(FTPLIB_BUFSIZ);
    if (ctrl->buf == NULL)
    {
	perror("calloc");
	net_close(sControl);
	free(ctrl);
	return 0;
    }
    ctrl->handle = sControl;
    ctrl->dir = FTPLIB_CONTROL;
    ctrl->ctrl = NULL;
    ctrl->cmode = FTPLIB_DEFMODE;
    ctrl->idlecb = NULL;
    ctrl->idletime.tv_sec = ctrl->idletime.tv_usec = 0;
    ctrl->idlearg = NULL;
    ctrl->xfered = 0;
    ctrl->xfered1 = 0;
    ctrl->cbbytes = 0;
    if (readresp('2', ctrl) == 0)
    {
	net_close(sControl);
	free(ctrl->buf);
	free(ctrl);
	return 0;
    }
    *nControl = ctrl;
    return 1;
}
Exemplo n.º 7
0
int
clip_TCPCONNECT(ClipMachine *mp)
{
	C_FILE *cf = NULL;
	struct sockaddr_in sin;
	long port = 0, timeout = 60000; /* maybe we should add _set_ for default timeout */
	int arg = 0, sock = -1, ret = -1, i;
	int *err = _clip_fetch_item(mp, HASH_ferror);
	struct timeval tv;
	char *addr  = _clip_parc(mp,1), *sport;

	*err=0;

	if (_clip_parinfo(mp,0) < 2 || _clip_parinfo(mp,1) != CHARACTER_t)
	{
		*err = EINVAL;
		goto err;
	}

	if (_clip_parinfo(mp,2) == NUMERIC_t)
		port = htons(_clip_parnl(mp,2));
	else if ((sport = _clip_parc(mp,2)) != NULL)
	{
		struct servent *sp;
		if ((sp = getservbyname( (const char *) sport, "tcp")) != NULL)
			port = sp->s_port;
		else
		{
			for (i = 0; sport[i] >= '0' && sport[i] <= '9'; i++);
			if (sport[i] == '\0')
				port = htons(atol(sport));
		}

	}

	if (port == 0)
	{
		*err = EINVAL;
		goto err;
	}

	if (_clip_parinfo(mp,3) == NUMERIC_t)
		timeout = _clip_parnl(mp,3);

	tv.tv_sec = timeout / 1000;
	tv.tv_usec = (timeout % 1000) * 1000;

	if ((sock = socket(AF_INET, SOCK_STREAM, 0)) == -1)
		goto err;

/*
#if !defined(linux) && !defined(SOLARIS_26_X86)
	setsockopt( sock, SOL_SOCKET, SO_SNDTIMEO, (void *)&tv,  sizeof(tv) );
	setsockopt( sock, SOL_SOCKET, SO_RCVTIMEO, (void *)&tv,  sizeof(tv) );
#endif
*/
	if ((arg = fcntl(sock, F_GETFL, 0)) == -1)
		goto err;
	fcntl(sock, F_SETFL, arg | O_NONBLOCK);

	sin.sin_family = AF_INET;
	sin.sin_port = port;
	tcp_host_addr(addr, &sin.sin_addr);

	if (sin.sin_addr.s_addr == INADDR_NONE)
	{
		*err = EFAULT;
		goto err;
	}

	if (connect( sock, (struct sockaddr *) &sin, sizeof(sin)) == -1 )
	{
		fd_set set;

#ifndef OS_MINGW
		if (errno != EINPROGRESS)
			goto err;
#endif

		FD_ZERO(&set);
		FD_SET(sock, &set);

		do  i = _clip_select( sock+1, NULL, &set, NULL, &tv );
		while (i == -1 && errno == EINTR);

		if (i == -1)
			goto err;
		else if (i == 0)
		{
#ifdef OS_MINGW
			*err = EAGAIN;
#else
			*err = ETIMEDOUT;
#endif
		}

		arg = 0;
		i = sizeof(arg);
		if (getsockopt(sock, SOL_SOCKET, SO_ERROR, (void *) &arg, (socklen_t *)(&i)) == -1)
			goto err;
		if (arg != 0)
		{
			*err = arg;
			goto err;
		}
	}

#ifndef OS_MINGW
	if ((arg = fcntl(sock, F_GETFL, 0)) == -1)
		goto err;
	fcntl(sock, F_SETFL, arg | O_NONBLOCK);
#endif

	cf = calloc(1, sizeof(C_FILE));
	cf->fileno = sock;
	cf->f = NULL;
	cf->type = FT_SOCKET;
	cf->pid = -1;
	cf->timeout = timeout;
	cf->stat = 0; /* see FS_* flags */
	ret = _clip_store_c_item(mp, cf, _C_ITEM_TYPE_FILE, destroy_c_file);

	err:
	if (ret == -1)
	{
		if (*err !=0 )
			*err = errno;
		if (sock != -1)
			close(sock);
	}
	_clip_retni(mp, ret);

	return 0;
}
Exemplo n.º 8
0
static int
rdate(const char *hostname, time_t *retval)
{
  struct servent *sent;
  struct sockaddr_in saddr;
  int fd;
  unsigned char time_buf[4];
  int nr, n_toread;

  assert(hostname);
  assert(retval);

  saddr.sin_family = AF_INET;

  if(!inet_aton(hostname, &saddr.sin_addr))
    {
      struct hostent *hent;

      hent = gethostbyname(hostname);
      if(!hent)
	{
	  fprintf(stderr, "%s: Unknown host %s: %s\n", program_invocation_short_name, hostname, hstrerror(h_errno));
	  return -1;
	}

      assert(hent->h_addrtype == AF_INET);
      memcpy(&saddr.sin_addr, hent->h_addr_list[0], hent->h_length);
    }

  if((sent = getservbyname("time", "tcp")))
    saddr.sin_port = sent->s_port;      
  else
    saddr.sin_port = htons(DEFAULT_PORT);

  fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
  if(fd < 0)
    {
      fprintf(stderr, "%s: couldn't create socket: %s\n", program_invocation_short_name, strerror(errno));
      return -1;
    }

  if(connect(fd, (struct sockaddr *)&saddr, sizeof(saddr)))
    {
      fprintf(stderr, "%s: couldn't connect to host %s: %s\n", program_invocation_short_name, hostname, strerror(errno));
      close(fd);
      return -1;
    }

  for(n_toread = sizeof(time_buf), nr = 1; nr > 0 && n_toread > 0; n_toread -= nr)
    nr = read(fd, time_buf + sizeof(time_buf) - n_toread, n_toread);
  if(n_toread)
    {
      if(nr)
	fprintf(stderr, "%s: error in read: %s\n", program_invocation_short_name, strerror(errno));
      else
	fprintf(stderr, "%s: got EOF from time server\n", program_invocation_short_name);
      close(fd);

      return -1;
    }

  /* See inetd's builtins.c for an explanation */
  *retval = (time_t)(ntohl(*(uint32_t *)time_buf) - 2208988800UL);

  return 0;
}
Exemplo n.º 9
0
int mcpOpen(char *name)
{
  char host[MAXHOSTNAMELEN], service[MAXHOSTNAMELEN];

  char buf[1024];

  char *cptr;
  int count, status;

  int sock_fd;
  struct hostent *hp;
  struct servent *sp;
  struct in_addr tmpaddr;
  int optval;

  struct sockaddr_in	inet_a;  // inet_addr is a function name

#ifndef _WIN32
  char path[MAXPATHLEN];
  struct sockaddr_un	unix_addr;
  size_t		unix_addr_len;

#endif //WIN32

#ifdef _WIN32
  // make sure we are initialized
  extern struct { int initialized; } initializer;
  if (initializer.initialized == 0)
	  return -1;
#endif //WIN32

  /*
   * Parse the name string.
   *
   *  A. If there is a ':' then it is an internet socket connection.
   *	1. Parse the name into <host>:<service> format.
   *	  a. If host is empty, use "localhost".
   *	  b. Lookup service with getservbyname().  If found, use
   *	     that port value.  If not found, attempt to convert
   *	     it to an integer and use that port value.
   *	2. Connect to <host>:<port>.  If the connection fails,
   *	   attempt to connect to <host>:tcpmux then request <service>
   *	   from tcpmux.
   *  B. Else the name is a unix domain socket name.
   *    1. If the first character is not '/', prepend '/tmp/' to the
   *	   name string.
   *	2. Connect to the socket name.
   */

  cptr = strchr(name, ':');

  if (cptr)
  {
    /* Copy the host name */
    if (cptr == name)
    {
      strcpy(host, "localhost");
    }
    else
    {
      strncpy(host, name, (cptr - name));
      host[cptr-name] = '\0';
    }

    /* Copy the service name */
    strcpy(service, cptr + 1);

    /* Initialize the inet_a struct */
    bzero((char *) &inet_a, sizeof(inet_a));
    inet_a.sin_family = AF_INET;

    /* Attempt to convert the host address as a dotted decimal number */
#ifdef _WIN32
    tmpaddr.s_addr = inet_addr(host);
    status = (tmpaddr.s_addr != INADDR_NONE) ? 1 : 0;
#else
    status = inet_aton(host, &tmpaddr);
#endif //WIN32
    if (status == 1)
    {
      bcopy((char *) &tmpaddr, (char *) &inet_a.sin_addr, sizeof(tmpaddr));
    }
    else
    {
      /* Now find the host */
      hp = gethostbyname(host);

      if (!hp)
      {
	/* We could not find the host */
	errno = ENOENT;
	return -1;
      }

      bcopy(hp->h_addr, (char *) &inet_a.sin_addr, hp->h_length);
    }

    /* Attempt to decode the service parameter */
    sp = getservbyname(service, "tcp");

    if (sp)
    {
      inet_a.sin_port = sp->s_port;
    }
    else
    {
      /* Attempt to convert the service name as an integer */
      inet_a.sin_port = htons((unsigned short)atoi(service));
    }

    /* Create the socket */
    sock_fd = socket(AF_INET, SOCK_STREAM, 0);
    if (sock_fd < 0)
    {
      return -1;
    }

    status = connect(sock_fd, (struct sockaddr *) &inet_a,
                     sizeof(inet_a));

    if (status < 0)
    {
      int status2;
      /*
       * The connection failed, try connecting to the tcpmux service.
       * tcpmux is at the well known port 1 so I just hardcoded it.
       */
      inet_a.sin_port = htons(1);

      status = errno;
      status2 = connect(sock_fd, (struct sockaddr *) &inet_a,
                        sizeof(inet_a));
      if (status2 < 0)
      {
		closefd(sock_fd);
		errno = status;
		return -1;
      }

      /*
       * We connected to tcpmux, now send the service name and see if
       * tcpmux can give it to us.  The tcpmux protocol works as follows:
       *
       *  1 Connect to the tcpmux port
       *  2 write the name of the service that you want followed by <CRLF>.
       *  3 read back the response terminated by <CRLF>
       *    a If the first character is a '+' then we are connected.
       *    b if the first character is a '-' then we are not connected.
       */
      sprintf(buf, "%s\r\n", service);
      status = mcpWrite(sock_fd, buf, (unsigned int) strlen(buf));
      if (status != (int)strlen(buf))
      {
		status = errno;
		closefd(sock_fd);
		errno = status;
		return -1;
      }

      /* Read up through the <CRLF> pair */
      /* There will be at least 3 characters coming back */
      cptr = buf;
      count = 3;
      while (1)
      {
		status = mcpRead(sock_fd, cptr, count);
		if (status <= 0)
		{
		  status = errno;
		  closefd(sock_fd);
		  errno = status;
		  return -1;
		}

		cptr += status;
		if (cptr[-1] == '\n')
		{
		  break;
		}
		else if (cptr[-1] == '\r')
		{
		  count = 1;
		}
		else
		{
		  count = 2;
		}
      }

      if (buf[0] != '+')
      {
		closefd(sock_fd);
#ifdef _WIN32
		errno = WSAECONNREFUSED;
		WSASetLastError (WSAECONNREFUSED);
#else
		errno = ECONNREFUSED;
#endif //WIN32
		return -1;
	  }
    }

    /*
     * We did it!  We actually succeeded in connecting to the name
     * via internet sockets.  Now make sure that we can send small
     * packets without delay.
     */
    optval = 1;
    status = setsockopt(sock_fd, IPPROTO_TCP, TCP_NODELAY, (void *)&optval,
			sizeof(optval));
  }
  else /* This must be a unix domain socket name */
  {
#ifndef _WIN32 // {
    /* Initialize the unix_addr struct */
    bzero((char *) &unix_addr, sizeof(unix_addr));
    unix_addr.sun_family = AF_UNIX;

    /*
     * If there is a leading '/' in the name name, it is an
     * absolute path name, otherwise, it is relative to /tmp.
     */
    if (name[0] == '/')
    {
      strcpy(path, name);
    }
    else
    {
      sprintf(path, "/tmp/%s", name);
    }

    strcpy(unix_addr.sun_path, path);
    unix_addr_len = /*sizeof(unix_addr.sun_len) + */ sizeof(unix_addr.sun_family) + strlen(path);

    /* Create the socket */
    sock_fd = socket(AF_UNIX, SOCK_STREAM, 0);
    if (sock_fd < 0)
    {
      return -1;
    }

    /* Connect to the name */
    status = connect(sock_fd, (struct sockaddr *) &unix_addr, unix_addr_len);
    if (status < 0)
    {
      closefd(sock_fd);
      return -1;
    }

    /*
     * We did it!  We actually succeeded in connecting to the name
     * via unix sockets.
     */
#else // } {
	HANDLE h;
	void* pmem;
	DWORD *mask, bit;
	struct sockmap* map;
	int i;
	
	h = CreateFileMapping(INVALID_HANDLE_VALUE, 0, 
		PAGE_READWRITE,
		0, MAYA_UNIX_SOCKET_SHARE_SIZE,
		MAYA_UNIX_SOCKET_SHARE_NAME);
	if (!h)
		return -1;
	if (GetLastError() != ERROR_ALREADY_EXISTS)
	{
		/* no "unix" handles exist */
		CloseHandle(h);
		return -1;
	}
	
	pmem = MapViewOfFile(h, FILE_MAP_WRITE,	0, 0, 0);
	if (!pmem)
	{
		CloseHandle(h);
		return -1;
	}
	mask = (DWORD*)pmem;
	map = (struct sockmap*)((char*)pmem+sizeof(DWORD));

	/* check if name is already here */
	sock_fd = -1;
	for (bit = 1, i = 0; i < 32; ++i)
	{
		if (*mask & bit)
		{
			if (strcmp(map[i].unix_path, name) == 0)
				break; /* found */
		}
		bit = bit << 1;
	}
	
	/* found */
	if (i < 32)
	{
		/* Initialize the inet_a struct */
		bzero((char *) &inet_a, sizeof(inet_a));
		inet_a.sin_family = AF_INET;

		/* Now find the host */
		hp = gethostbyname("localhost");
		if (!hp)
			errno = ENOENT;
		else
		{
			bcopy(hp->h_addr, (char *) &inet_a.sin_addr, hp->h_length);
			inet_a.sin_port = map[i].port;

			/* Create the socket */
			sock_fd = socket(AF_INET, SOCK_STREAM, 0);
			if (sock_fd >= 0)
			{
				status = connect(sock_fd, (struct sockaddr*)&inet_a, sizeof(inet_a));
				if (status < 0)
				{
					closefd(sock_fd);
					sock_fd = -1;
					errno = status;
				}
				else
				{
					optval = 1;
					status = setsockopt(sock_fd, IPPROTO_TCP, TCP_NODELAY,
						(char*)&optval, sizeof(optval));
				}
			}
		}
	}

	UnmapViewOfFile(pmem);
	CloseHandle(h);

#endif //WIN32 }
  }

  /* Ok, we are connected.  Return the socket descriptor */
  return sock_fd;
}
Exemplo n.º 10
0
/*-
 * BIO_lookup - look up the node and service you want to connect to.
 * @node: the node you want to connect to.
 * @service: the service you want to connect to.
 * @lookup_type: declare intent with the result, client or server.
 * @family: the address family you want to use.  Use AF_UNSPEC for any, or
 *  AF_INET, AF_INET6 or AF_UNIX.
 * @socktype: The socket type you want to use.  Can be SOCK_STREAM, SOCK_DGRAM
 *  or 0 for all.
 * @res: Storage place for the resulting list of returned addresses
 *
 * This will do a lookup of the node and service that you want to connect to.
 * It returns a linked list of different addresses you can try to connect to.
 *
 * When no longer needed you should call BIO_ADDRINFO_free() to free the result.
 *
 * The return value is 1 on success or 0 in case of error.
 */
int BIO_lookup(const char *host, const char *service,
               enum BIO_lookup_type lookup_type,
               int family, int socktype, BIO_ADDRINFO **res)
{
    int ret = 0;                 /* Assume failure */

    switch(family) {
    case AF_INET:
#ifdef AF_INET6
    case AF_INET6:
#endif
#ifdef AF_UNIX
    case AF_UNIX:
#endif
#ifdef AF_UNSPEC
    case AF_UNSPEC:
#endif
        break;
    default:
        BIOerr(BIO_F_BIO_LOOKUP, BIO_R_UNSUPPORTED_PROTOCOL_FAMILY);
        return 0;
    }

#ifdef AF_UNIX
    if (family == AF_UNIX) {
        if (addrinfo_wrap(family, socktype, host, strlen(host), 0, res))
            return 1;
        else
            BIOerr(BIO_F_BIO_LOOKUP, ERR_R_MALLOC_FAILURE);
        return 0;
    }
#endif

    if (BIO_sock_init() != 1)
        return 0;

    if (1) {
#ifdef AI_PASSIVE
        int gai_ret = 0;
        struct addrinfo hints;

        memset(&hints, 0, sizeof hints);

        hints.ai_family = family;
        hints.ai_socktype = socktype;

        if (lookup_type == BIO_LOOKUP_SERVER)
            hints.ai_flags |= AI_PASSIVE;

        /* Note that |res| SHOULD be a 'struct addrinfo **' thanks to
         * macro magic in bio_lcl.h
         */
        switch ((gai_ret = getaddrinfo(host, service, &hints, res))) {
# ifdef EAI_SYSTEM
        case EAI_SYSTEM:
            SYSerr(SYS_F_GETADDRINFO, get_last_socket_error());
            BIOerr(BIO_F_BIO_LOOKUP, ERR_R_SYS_LIB);
            break;
# endif
        case 0:
            ret = 1;             /* Success */
            break;
        default:
            BIOerr(BIO_F_BIO_LOOKUP, ERR_R_SYS_LIB);
            ERR_add_error_data(1, gai_strerror(gai_ret));
            break;
        }
    } else {
#endif
        const struct hostent *he;
/*
 * Because struct hostent is defined for 32-bit pointers only with
 * VMS C, we need to make sure that '&he_fallback_address' and
 * '&he_fallback_addresses' are 32-bit pointers
 */
#if defined(OPENSSL_SYS_VMS) && defined(__DECC)
# pragma pointer_size save
# pragma pointer_size 32
#endif
        /* Windows doesn't seem to have in_addr_t */
#ifdef OPENSSL_SYS_WINDOWS
        static uint32_t he_fallback_address;
        static const char *he_fallback_addresses[] =
            { (char *)&he_fallback_address, NULL };
#else
        static in_addr_t he_fallback_address;
        static const char *he_fallback_addresses[] =
            { (char *)&he_fallback_address, NULL };
#endif
        static const struct hostent he_fallback =
            { NULL, NULL, AF_INET, sizeof(he_fallback_address),
              (char **)&he_fallback_addresses };
#if defined(OPENSSL_SYS_VMS) && defined(__DECC)
# pragma pointer_size restore
#endif

        struct servent *se;
        /* Apparently, on WIN64, s_proto and s_port have traded places... */
#ifdef _WIN64
        struct servent se_fallback = { NULL, NULL, NULL, 0 };
#else
        struct servent se_fallback = { NULL, NULL, 0, NULL };
#endif

        if (!RUN_ONCE(&bio_lookup_init, do_bio_lookup_init)) {
            BIOerr(BIO_F_BIO_LOOKUP, ERR_R_MALLOC_FAILURE);
            ret = 0;
            goto err;
        }

        CRYPTO_THREAD_write_lock(bio_lookup_lock);
        he_fallback_address = INADDR_ANY;
        if (host == NULL) {
            he = &he_fallback;
            switch(lookup_type) {
            case BIO_LOOKUP_CLIENT:
                he_fallback_address = INADDR_LOOPBACK;
                break;
            case BIO_LOOKUP_SERVER:
                he_fallback_address = INADDR_ANY;
                break;
            default:
                OPENSSL_assert(("We forgot to handle a lookup type!" == 0));
                break;
            }
        } else {
            he = gethostbyname(host);

            if (he == NULL) {
#ifndef OPENSSL_SYS_WINDOWS
                /*
                 * This might be misleading, because h_errno is used as if
                 * it was errno. To minimize mixup add 1000. Underlying
                 * reason for this is that hstrerror is declared obsolete,
                 * not to mention that a) h_errno is not always guaranteed
                 * to be meaningless; b) hstrerror can reside in yet another
                 * library, linking for sake of hstrerror is an overkill;
                 * c) this path is not executed on contemporary systems
                 * anyway [above getaddrinfo/gai_strerror is]. We just let
                 * system administrator figure this out...
                 */
                SYSerr(SYS_F_GETHOSTBYNAME, 1000 + h_errno);
#else
                SYSerr(SYS_F_GETHOSTBYNAME, WSAGetLastError());
#endif
                ret = 0;
                goto err;
            }
        }

        if (service == NULL) {
            se_fallback.s_port = 0;
            se_fallback.s_proto = NULL;
            se = &se_fallback;
        } else {
            char *endp = NULL;
            long portnum = strtol(service, &endp, 10);

/*
 * Because struct servent is defined for 32-bit pointers only with
 * VMS C, we need to make sure that 'proto' is a 32-bit pointer.
 */
#if defined(OPENSSL_SYS_VMS) && defined(__DECC)
# pragma pointer_size save
# pragma pointer_size 32
#endif
            char *proto = NULL;
#if defined(OPENSSL_SYS_VMS) && defined(__DECC)
# pragma pointer_size restore
#endif

            switch (socktype) {
            case SOCK_STREAM:
                proto = "tcp";
                break;
            case SOCK_DGRAM:
                proto = "udp";
                break;
            }

            if (endp != service && *endp == '\0'
                    && portnum > 0 && portnum < 65536) {
                se_fallback.s_port = htons(portnum);
                se_fallback.s_proto = proto;
                se = &se_fallback;
            } else if (endp == service) {
                se = getservbyname(service, proto);

                if (se == NULL) {
#ifndef OPENSSL_SYS_WINDOWS
                    SYSerr(SYS_F_GETSERVBYNAME, errno);
#else
                    SYSerr(SYS_F_GETSERVBYNAME, WSAGetLastError());
#endif
                    goto err;
                }
            } else {
                BIOerr(BIO_F_BIO_LOOKUP, BIO_R_MALFORMED_HOST_OR_SERVICE);
                goto err;
            }
        }

        *res = NULL;

        {
/*
 * Because hostent::h_addr_list is an array of 32-bit pointers with VMS C,
 * we must make sure our iterator designates the same element type, hence
 * the pointer size dance.
 */
#if defined(OPENSSL_SYS_VMS) && defined(__DECC)
# pragma pointer_size save
# pragma pointer_size 32
#endif
            char **addrlistp;
#if defined(OPENSSL_SYS_VMS) && defined(__DECC)
# pragma pointer_size restore
#endif
            size_t addresses;
            BIO_ADDRINFO *tmp_bai = NULL;

            /* The easiest way to create a linked list from an
               array is to start from the back */
            for(addrlistp = he->h_addr_list; *addrlistp != NULL;
                addrlistp++)
                ;

            for(addresses = addrlistp - he->h_addr_list;
                addrlistp--, addresses-- > 0; ) {
                if (!addrinfo_wrap(he->h_addrtype, socktype,
                                   *addrlistp, he->h_length,
                                   se->s_port, &tmp_bai))
                    goto addrinfo_malloc_err;
                tmp_bai->bai_next = *res;
                *res = tmp_bai;
                continue;
             addrinfo_malloc_err:
                BIO_ADDRINFO_free(*res);
                *res = NULL;
                BIOerr(BIO_F_BIO_LOOKUP, ERR_R_MALLOC_FAILURE);
                ret = 0;
                goto err;
            }

            ret = 1;
        }
     err:
        CRYPTO_THREAD_unlock(bio_lookup_lock);
    }

    return ret;
}
Exemplo n.º 11
0
/*
 * The timedaemons synchronize the clocks of hosts in a local area network.
 * One daemon runs as master, all the others as slaves. The master
 * performs the task of computing clock differences and sends correction
 * values to the slaves.
 * Slaves start an election to choose a new master when the latter disappears
 * because of a machine crash, network partition, or when killed.
 * A resolution protocol is used to kill all but one of the masters
 * that happen to exist in segments of a partitioned network when the
 * network partition is fixed.
 *
 * Authors: Riccardo Gusella & Stefano Zatti
 *
 * overhauled at Silicon Graphics
 */
int
main(int argc, char *argv[])
{
	int on;
	int ret;
	int nflag, iflag;
	struct timeval ntime;
	struct servent *srvp;
	char buf[BUFSIZ], *cp, *cplim;
	struct ifconf ifc;
	struct ifreq ifreq, ifreqf, *ifr;
	register struct netinfo *ntp;
	struct netinfo *ntip;
	struct netinfo *savefromnet;
	struct netent *nentp;
	struct nets *nt;
	struct sockaddr_in server;
	u_short port;
	int c;

#ifdef lint
	ntip = NULL;
#endif

	on = 1;
	nflag = OFF;
	iflag = OFF;


	opterr = 0;
	while ((c = getopt(argc, argv, "Mtdn:i:F:G:P:")) != -1) {
		switch (c) {
		case 'M':
			Mflag = 1;
			break;

		case 't':
			trace = 1;
			break;

		case 'n':
			if (iflag) {
				errx(1, "-i and -n make no sense together");
			} else {
				nflag = ON;
				addnetname(optarg);
			}
			break;

		case 'i':
			if (nflag) {
				errx(1, "-i and -n make no sense together");
			} else {
				iflag = ON;
				addnetname(optarg);
			}
			break;

		case 'F':
			add_good_host(optarg,1);
			while (optind < argc && argv[optind][0] != '-')
				add_good_host(argv[optind++], 1);
			break;

		case 'd':
			debug = 1;
			break;
		case 'G':
			if (goodgroup != NULL)
				errx(1, "only one net group");
			goodgroup = optarg;
			break;

		default:
			usage();
			break;
		}
	}
	if (optind < argc)
		usage();

	/* If we care about which machine is the master, then we must
	 *	be willing to be a master
	 */
	if (goodgroup != NULL || goodhosts != NULL)
		Mflag = 1;

	if (gethostname(hostname, sizeof(hostname) - 1) < 0)
		err(1, "gethostname");
	self.l_bak = &self;
	self.l_fwd = &self;
	self.h_bak = &self;
	self.h_fwd = &self;
	self.head = 1;
	self.good = 1;

	if (goodhosts != NULL)		/* trust ourself */
		add_good_host(hostname,1);

	srvp = getservbyname("timed", "udp");
	if (srvp == NULL)
		errx(1, "timed/udp: unknown service");
	port = srvp->s_port;
	bzero(&server, sizeof(struct sockaddr_in));
	server.sin_port = srvp->s_port;
	server.sin_family = AF_INET;
	sock = socket(AF_INET, SOCK_DGRAM, 0);
	if (sock < 0)
		err(1, "socket");
	if (setsockopt(sock, SOL_SOCKET, SO_BROADCAST, (char *)&on,
							sizeof(on)) < 0)
		err(1, "setsockopt");
	if (bind(sock, (struct sockaddr*)&server, sizeof(server))) {
		if (errno == EADDRINUSE)
			warnx("time daemon already running");
		else
			warn("bind");
		exit(1);
	}

	sequence = arc4random();     /* initial seq number */

	(void)gettimeofday(&ntime, NULL);
	/* rounds kernel variable time to multiple of 5 ms. */
	ntime.tv_sec = 0;
	ntime.tv_usec = -((ntime.tv_usec/1000) % 5) * 1000;
	(void)adjtime(&ntime, (struct timeval *)0);

	for (nt = nets; nt; nt = nt->next) {
		nentp = getnetbyname(nt->name);
		if (nentp == NULL) {
			nt->net = inet_network(nt->name);
			if (nt->net != INADDR_NONE)
				nentp = getnetbyaddr(nt->net, AF_INET);
		}
		if (nentp != NULL) {
			nt->net = nentp->n_net;
		} else if (nt->net == INADDR_NONE) {
			errx(1, "unknown net %s", nt->name);
		} else if (nt->net == INADDR_ANY) {
			errx(1, "bad net %s", nt->name);
		} else {
			warnx("warning: %s unknown in /etc/networks",
				nt->name);
		}

		if (0 == (nt->net & 0xff000000))
		    nt->net <<= 8;
		if (0 == (nt->net & 0xff000000))
		    nt->net <<= 8;
		if (0 == (nt->net & 0xff000000))
		    nt->net <<= 8;
	}
	ifc.ifc_len = sizeof(buf);
	ifc.ifc_buf = buf;
	if (ioctl(sock, SIOCGIFCONF, (char *)&ifc) < 0)
		err(1, "get interface configuration");
	ntp = NULL;
#define size(p)	max((p).sa_len, sizeof(p))
	cplim = buf + ifc.ifc_len; /*skip over if's with big ifr_addr's */
	for (cp = buf; cp < cplim;
			cp += sizeof (ifr->ifr_name) + size(ifr->ifr_addr)) {
		ifr = (struct ifreq *)cp;
		if (ifr->ifr_addr.sa_family != AF_INET)
			continue;
		if (!ntp)
			ntp = (struct netinfo*)malloc(sizeof(struct netinfo));
		bzero(ntp,sizeof(*ntp));
		ntp->my_addr=((struct sockaddr_in *)&ifr->ifr_addr)->sin_addr;
		ntp->status = NOMASTER;
		ifreq = *ifr;
		ifreqf = *ifr;

		if (ioctl(sock, SIOCGIFFLAGS, (char *)&ifreqf) < 0) {
			warn("get interface flags");
			continue;
		}
		if ((ifreqf.ifr_flags & IFF_UP) == 0)
			continue;
		if ((ifreqf.ifr_flags & IFF_BROADCAST) == 0 &&
		    (ifreqf.ifr_flags & IFF_POINTOPOINT) == 0) {
			continue;
		}


		if (ioctl(sock, SIOCGIFNETMASK, (char *)&ifreq) < 0) {
			warn("get netmask");
			continue;
		}
		ntp->mask = ((struct sockaddr_in *)
			&ifreq.ifr_addr)->sin_addr.s_addr;

		if (ifreqf.ifr_flags & IFF_BROADCAST) {
			if (ioctl(sock, SIOCGIFBRDADDR, (char *)&ifreq) < 0) {
				warn("get broadaddr");
				continue;
			}
			ntp->dest_addr = *(struct sockaddr_in *)&ifreq.ifr_broadaddr;
			/* What if the broadcast address is all ones?
			 * So we cannot just mask ntp->dest_addr.  */
			ntp->net = ntp->my_addr;
			ntp->net.s_addr &= ntp->mask;
		} else {
			if (ioctl(sock, SIOCGIFDSTADDR,
						(char *)&ifreq) < 0) {
				warn("get destaddr");
				continue;
			}
			ntp->dest_addr = *(struct sockaddr_in *)&ifreq.ifr_dstaddr;
			ntp->net = ntp->dest_addr.sin_addr;
		}

		ntp->dest_addr.sin_port = port;

		for (nt = nets; nt; nt = nt->next) {
			if (ntp->net.s_addr == htonl(nt->net))
				break;
		}
		if ((nflag && !nt) || (iflag && nt))
			continue;

		ntp->next = NULL;
		if (nettab == NULL) {
			nettab = ntp;
		} else {
			ntip->next = ntp;
		}
		ntip = ntp;
		ntp = NULL;
	}
	if (ntp)
		(void) free((char *)ntp);
	if (nettab == NULL)
		errx(1, "no network usable");

	/* microseconds to delay before responding to a broadcast */
	delay1 = casual(1, 100*1000);

	/* election timer delay in secs. */
	delay2 = casual(MINTOUT, MAXTOUT);

	if (!debug)
		daemon(debug, 0);

	if (trace)
		traceon();
	openlog("timed", LOG_CONS|LOG_PID, LOG_DAEMON);

	/*
	 * keep returning here
	 */
	ret = setjmp(jmpenv);
	savefromnet = fromnet;
	setstatus();

	if (Mflag) {
		switch (ret) {

		case 0:
			checkignorednets();
			pickslavenet(0);
			break;
		case 1:
			/* Just lost our master */
			if (slavenet != NULL)
				slavenet->status = election(slavenet);
			if (!slavenet || slavenet->status == MASTER) {
				checkignorednets();
				pickslavenet(0);
			} else {
				makeslave(slavenet);	/* prune extras */
			}
			break;

		case 2:
			/* Just been told to quit */
			justquit = 1;
			pickslavenet(savefromnet);
			break;
		}

		setstatus();
		if (!(status & MASTER) && sock_raw != -1) {
			/* sock_raw is not being used now */
			(void)close(sock_raw);
			sock_raw = -1;
		}

		if (status == MASTER)
			master();
		else
			slave();

	} else {
		if (sock_raw != -1) {
			(void)close(sock_raw);
			sock_raw = -1;
		}

		if (ret) {
			/* we just lost our master or were told to quit */
			justquit = 1;
		}
		for (ntp = nettab; ntp != NULL; ntp = ntp->next) {
			if (ntp->status == MASTER) {
				rmnetmachs(ntp);
				ntp->status = NOMASTER;
			}
		}
		checkignorednets();
		pickslavenet(0);
		setstatus();

		slave();
	}
	/* NOTREACHED */
	return(0);
}
Exemplo n.º 12
0
int
krb4int_send_to_kdc_addr(
    KTEXT pkt, KTEXT rpkt, char *realm,
    struct sockaddr *addr, socklen_t *addrlen)
{
    struct addrlist	al = ADDRLIST_INIT;
    char		lrealm[REALM_SZ];
    krb5int_access	internals;
    krb5_error_code	retval;
    struct servent	*sp;
    int			krb_udp_port = 0;
    int			krbsec_udp_port = 0;
    char		krbhst[MAXHOSTNAMELEN];
    char		*scol;
    int			i;
    int			err;
    krb5_data		message, reply;

    /*
     * If "realm" is non-null, use that, otherwise get the
     * local realm.
     */
    if (realm)
	strncpy(lrealm, realm, sizeof(lrealm) - 1);
    else {
	if (krb_get_lrealm(lrealm, 1)) {
	    DEB (("%s: can't get local realm\n", prog));
	    return SKDC_CANT;
	}
    }
    lrealm[sizeof(lrealm) - 1] = '\0';
    DEB (("lrealm is %s\n", lrealm));

    retval = krb5int_accessor(&internals, KRB5INT_ACCESS_VERSION);
    if (retval)
	return KFAILURE;

    /* The first time, decide what port to use for the KDC.  */
    if (cached_krb_udp_port == 0) {
	sp = getservbyname("kerberos","udp");
        if (sp)
	    cached_krb_udp_port = sp->s_port;
	else
	    cached_krb_udp_port = htons(KERBEROS_PORT); /* kerberos/udp */
        DEB (("cached_krb_udp_port is %d\n", cached_krb_udp_port));
    }
    /* If kerberos/udp isn't 750, try using kerberos-sec/udp (or 750) 
       as a fallback. */
    if (cached_krbsec_udp_port == 0 && 
	cached_krb_udp_port != htons(KERBEROS_PORT)) {
	sp = getservbyname("kerberos-sec","udp");
        if (sp)
	    cached_krbsec_udp_port = sp->s_port;
	else
	    cached_krbsec_udp_port = htons(KERBEROS_PORT); /* kerberos/udp */
        DEB (("cached_krbsec_udp_port is %d\n", cached_krbsec_udp_port));
    }

    for (i = 1; krb_get_krbhst(krbhst, lrealm, i) == KSUCCESS; ++i) {
#ifdef DEBUG
        if (krb_debug) {
            DEB (("Getting host entry for %s...",krbhst));
            (void) fflush(stdout);
        }
#endif
	if (0 != (scol = strchr(krbhst,':'))) {
	    krb_udp_port = htons(atoi(scol+1));
	    *scol = 0;
	    if (krb_udp_port == 0) {
#ifdef DEBUG
		if (krb_debug) {
		    DEB (("bad port number %s\n",scol+1));
		    (void) fflush(stdout);
		}
#endif
		continue;
	    }
	    krbsec_udp_port = 0;
	} else {
	    krb_udp_port = cached_krb_udp_port;
	    krbsec_udp_port = cached_krbsec_udp_port;
	}
        err = internals.add_host_to_list(&al, krbhst,
					 krb_udp_port, krbsec_udp_port,
					 SOCK_DGRAM, PF_INET);
	if (err) {
	    retval = SKDC_CANT;
	    goto free_al;
	}
    }
    if (al.naddrs == 0) {
	DEB (("%s: can't find any Kerberos host.\n", prog));
        retval = SKDC_CANT;
    }

    message.length = pkt->length;
    message.data = (char *)pkt->dat; /* XXX yuck */
    retval = internals.sendto_udp(NULL, &message, &al, NULL, &reply, addr,
				  addrlen, NULL, 0, NULL);
    DEB(("sendto_udp returns %d\n", retval));
free_al:
    internals.free_addrlist(&al);
    if (retval)
	return SKDC_CANT;
    DEB(("reply.length=%d\n", reply.length));
    if (reply.length > sizeof(rpkt->dat))
	retval = SKDC_CANT;
    rpkt->length = 0;
    if (!retval) {
	memcpy(rpkt->dat, reply.data, reply.length);
	rpkt->length = reply.length;
    }
    krb5_free_data_contents(NULL, &reply);
    return retval;
}
Exemplo n.º 13
0
/*
 * FtpConnect - connect to remote server
 *
 * return 1 if connected, 0 if not
 */
GLOBALDEF int FtpConnect(const char *host, netbuf **nControl)
{
    int sControl, stat, flags, oldflags;
    struct sockaddr_in sin;
    struct hostent *phe;
    struct servent *pse;
    int on=1;
    netbuf *ctrl;
    char *lhost;
    char *pnum;
    struct timeval tv;
    fd_set wr;

    memset(&sin,0,sizeof(sin));
    sin.sin_family = AF_INET;
    lhost = strdup(host);
    pnum = strchr(lhost,':');
    if (pnum == NULL)
      {
#if defined(VMS) || defined(ANDROID)
          sin.sin_port = htons(21);
#else
          if ((pse = getservbyname("ftp","tcp")) == NULL)
            {
                perror("getservbyname");
                return 0;
            }
          sin.sin_port = pse->s_port;
#endif
      }
    else
      {
          *pnum++ = '\0';
          if (isdigit(*pnum))
              sin.sin_port = htons(atoi(pnum));
          else
            {
                pse = getservbyname(pnum,"tcp");
                sin.sin_port = pse->s_port;
            }
      }
    if ((sin.sin_addr.s_addr = inet_addr(lhost)) == -1)
      {
          if ((phe = gethostbyname(lhost)) == NULL)
            {
                perror("gethostbyname");
                return 0;
            }

          memcpy((char *)&sin.sin_addr, phe->h_addr, phe->h_length);

      }
    free(lhost);

    sControl = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
    if (sControl == -1)
      {
          perror("socket");
          return 0;
      }

    if ( setsockopt(sControl,SOL_SOCKET,SO_REUSEADDR,
                   SETSOCKOPT_OPTVAL_TYPE &on, sizeof(on)) == -1)
      {
          perror("setsockopt");
          net_close(sControl);
          return 0;
      }

#if defined(_WIN32)
	if (connect(sControl, (struct sockaddr *)&sin, sizeof(sin)) == -1)
	{
		perror("connect");
		net_close(sControl);
		return 0;
	}
#else
     //set nonblocking for connection timeout
    flags = fcntl( sControl, F_GETFL,0);
    oldflags=flags;
    fcntl( sControl, F_SETFL, O_NONBLOCK|flags);

    stat=connect( sControl, (struct sockaddr *)&sin, sizeof(sin));
    if (stat < 0) 
      { 
          if (errno != EWOULDBLOCK && errno != EINPROGRESS) 
            { 
                perror("connect");
                net_close(sControl);
                return 0;
            } 
      } 

    FD_ZERO(&wr); 
    FD_SET( sControl, &wr); 

    tv.tv_sec = ACCEPT_TIMEOUT;
    tv.tv_usec = 0; 

    stat = select(sControl+1, 0, &wr, 0, &tv);

    if (stat < 1)
      { 
            // time out has expired, 
            // or an error has ocurred
          perror("timeout");
          net_close(sControl);
          return 0;
      } 

    if (ftplib_debug > 1)
        printf("connected\n");

      //set original flags
    fcntl( sControl, F_SETFL, oldflags);
#endif

    ctrl = calloc(1,sizeof(netbuf));
    if (ctrl == NULL)
      {
          perror("calloc");
          net_close(sControl);
          return 0;
      }
    ctrl->buf = malloc(FTPLIB_BUFSIZ);
    if (ctrl->buf == NULL)
      {
          perror("calloc");
          net_close(sControl);
          free(ctrl);
          return 0;
      }
    ctrl->handle = sControl;
    ctrl->dir = FTPLIB_CONTROL;
    ctrl->ctrl = NULL;
    ctrl->cmode = FTPLIB_DEFMODE;
    ctrl->idlecb = NULL;
    ctrl->writercb = NULL;
    ctrl->idletime.tv_sec = ctrl->idletime.tv_usec = 0;
    ctrl->idlearg = NULL;
    ctrl->writerarg = NULL;
    ctrl->xfered = 0;
    ctrl->xfered1 = 0;
    ctrl->cbbytes = 0;
    if (readresp('2', ctrl) == 0)
      {
          net_close(sControl);
          free(ctrl->buf);
          free(ctrl);
          return 0;
      }
    *nControl = ctrl;
    return 1;
}
Exemplo n.º 14
0
int
main(int argc, char **argv)
{
    int     sockfd = 0;
    int     n = 0;
    char    recvline[MAXLINE + 1];
    struct  sockaddr_in     servaddr;
    struct  in_addr         **pptr = NULL;             //
    struct  in_addr         *inetaddrp[2];      //
    struct  in_addr         inetaddr;           //
    struct  hostent         *hp = NULL;
    struct  servent         *sp = NULL;

    if ( argc != 3 )
    {
         err_quit("usage: daytimetcpcli <hostname> <service>");
    }

    if ( (hp = gethostbyname(argv[1])) == NULL )
    {
        if (inet_aton(argv[1], &inetaddr) == 0)
        {
             err_quit("hostname error for %s: %s\n",
                      argv[1], hstrerror(h_errno));
        }
        else
        {
            inetaddrp[0] = &inetaddr;
            inetaddrp[1] = NULL;
            pptr = inetaddrp;           //注意是有p的.
        }
    }
    else
    {
         pptr = (struct in_addr **) hp->h_addr_list;
    }

    //获得了相应服务的端口号什么的
    if ( (sp = getservbyname(argv[2], "tcp")) == NULL )
    {
        err_quit("getservbyname error for %s\n", argv[2]);
    }

    for ( ; *pptr != NULL; pptr++ )
    {
         sockfd = my_socket(AF_INET, SOCK_STREAM, 0);

         bzero(&servaddr, sizeof(servaddr));
         servaddr.sin_family    = AF_INET;
         servaddr.sin_port      = sp->s_port;       //帅
         memcpy(&servaddr.sin_addr, *pptr, sizeof(struct in_addr));
         printf("trying %s\n",
                 my_sock_ntop((SA *) &servaddr, sizeof(servaddr)));

         if (connect(sockfd, (SA *) &servaddr, sizeof(servaddr)) == 0)
         {
              break;        //success
         }
         err_ret("connect error");
         close(sockfd);
    }

    if (*pptr == NULL)                  //这里不是很懂
    {
         err_quit("unable to connect");
    }

    while ((n= my_read(sockfd, recvline, MAXLINE)) > 0)
    {
        recvline[n] = 0;
        my_fputs(recvline, stdout);
    }

    exit (0);
}
Exemplo n.º 15
0
TCPSTREAM *tcp_open (char *host,char *service,unsigned long port)
{
  TCPSTREAM *stream = NIL;
  int i;
  int sock = -1;
  int ctr = 0;
  int silent = (port & NET_SILENT) ? T : NIL;
  int *ctrp = (port & NET_NOOPENTIMEOUT) ? NIL : &ctr;
  char *s;
  struct sockaddr_in sin;
  struct hostent *he;
  char hostname[MAILTMPLEN];
  char tmp[MAILTMPLEN];
  struct servent *sv = NIL;
  blocknotify_t bn = (blocknotify_t) mail_parameters (NIL,GET_BLOCKNOTIFY,NIL);
  void *data;
  port &= 0xffff;		/* erase flags */
				/* lookup service */
  if (service && (sv = getservbyname (service,"tcp")))
    port = ntohs (sin.sin_port = sv->s_port);
 				/* copy port number in network format */
  else sin.sin_port = htons (port);
  /* The domain literal form is used (rather than simply the dotted decimal
     as with other Amiga programs) because it has to be a valid "host name"
     in mailsystem terminology. */
				/* look like domain literal? */
  if (host[0] == '[' && host[(strlen (host))-1] == ']') {
    strcpy (hostname,host+1);	/* yes, copy number part */
    hostname[(strlen (hostname))-1] = '\0';
    if ((sin.sin_addr.s_addr = inet_addr (hostname)) == -1)
      sprintf (tmp,"Bad format domain-literal: %.80s",host);
    else {
      sin.sin_family = AF_INET;	/* family is always Internet */
      strcpy (hostname,host);	/* hostname is user's argument */
      (*bn) (BLOCK_TCPOPEN,NIL);
				/* get an open socket for this system */
      sock = tcp_socket_open (&sin,tmp,ctrp,hostname,port);
      (*bn) (BLOCK_NONE,NIL);
    }
  }

  else {			/* lookup host name */
    if (tcpdebug) {
      sprintf (tmp,"DNS resolution %.80s",host);
      mm_log (tmp,TCPDEBUG);
    }
    (*bn) (BLOCK_DNSLOOKUP,NIL);/* quell alarms */
    data = (*bn) (BLOCK_SENSITIVE,NIL);
    if (!(he = gethostbyname (lcase (strcpy (hostname,host)))))
      sprintf (tmp,"No such host as %.80s",host);
    (*bn) (BLOCK_NONSENSITIVE,data);
    (*bn) (BLOCK_NONE,NIL);
    if (he) {			/* DNS resolution won? */
      if (tcpdebug) mm_log ("DNS resolution done",TCPDEBUG);
				/* copy address type */
      sin.sin_family = he->h_addrtype;
				/* copy host name */
      strcpy (hostname,he->h_name);
#ifdef HOST_NOT_FOUND		/* muliple addresses only on DNS systems */
      for (sock = -1,i = 0; (sock < 0) && (s = he->h_addr_list[i]); i++) {
	if (i && !silent) mm_log (tmp,WARN);
	memcpy (&sin.sin_addr,s,he->h_length);
	(*bn) (BLOCK_TCPOPEN,NIL);
	sock = tcp_socket_open (&sin,tmp,ctrp,hostname,port);
	(*bn) (BLOCK_NONE,NIL);
      }
#else				/* the one true address then */
      memcpy (&sin.sin_addr,he->h_addr,he->h_length);
      (*bn) (BLOCK_TCPOPEN,NIL);
      sock = tcp_socket_open (&sin,tmp,ctrp,hostname,port);
      (*bn) (BLOCK_NONE,NIL);
#endif
    }
  }
  if (sock >= 0)  {		/* won */
    stream = (TCPSTREAM *) memset (fs_get (sizeof (TCPSTREAM)),0,
				   sizeof (TCPSTREAM));
    stream->port = port;	/* port number */
				/* init sockets */
    stream->tcpsi = stream->tcpso = sock;
				/* stash in the snuck-in byte */
    if (stream->ictr = ctr) *(stream->iptr = stream->ibuf) = tmp[0];
				/* copy official host name */
    stream->host = cpystr (hostname);
    if (tcpdebug) mm_log ("Stream open and ready for read",TCPDEBUG);
  }
  else if (!silent) mm_log (tmp,ERROR);
  return stream;		/* return success */
}
Exemplo n.º 16
0
static void printer_host_callback(void *arg, int status, int timeouts,
				  struct hostent *host)
{
  struct printer_poll_args *pargs = (struct printer_poll_args *) arg;
  struct printer *printer = pargs->printer;
  int s = -1, lport = IPPORT_RESERVED - 1, flags;
  unsigned short port;
  struct servent *servent;
  struct sockaddr_in sin;

  if (status == ARES_EDESTRUCTION)
    {
      syslog(LOG_DEBUG, "printer_host_callback: printer %s hostname query "
	     "halted for channel destruction", printer->name);
      free(pargs);
      return;
    }

  if (status != ARES_SUCCESS)
    {
      syslog(LOG_ERR, "printer_host_callback: printer %s can't resolve print "
	     "server name: %s", printer->name, ares_strerror(status));
      goto failure;
    }

  s = rresvport(&lport);
  if (s < 0)
    {
      syslog(LOG_ERR, "printer_host_callback: printer %s can't get reserved "
	     "port", printer->name);
      goto failure;
    }

  /* Set s non-blocking so we can do a non-blocking connect. */
  flags = fcntl(s, F_GETFL);
  fcntl(s, F_SETFL, flags | O_NONBLOCK);

  servent = getservbyname("printer", "tcp");
  port = (servent) ? servent->s_port : htons(PRINTER_FALLBACK_PORT);

  memset(&sin, 0, sizeof(sin));
  sin.sin_family = AF_INET;
  memcpy(&sin.sin_addr, host->h_addr, sizeof(sin.sin_addr));
  sin.sin_port = port;
  if (connect(s, (struct sockaddr *) &sin, sizeof(sin)) == -1
      && errno != EINPROGRESS)
    {
      syslog(LOG_ERR, "printer_host_callback: printer %s can't connect to "
	     "print server %s: %m", printer->name, host->h_name);
      goto failure;
    }

  /* Set up the request we want to send; the main loop will call
   * printer_handle_output() when the socket selects true for
   * writing.
   */
  printer->s = s;
  printer->to_send = 1;
  sprintf(printer->buf, "\3%.*s\n", (int)(sizeof(printer->buf) - 3),
	  printer->name);
  printer->buflen = strlen(printer->buf);
  printer->jobs_counted = 0;
  printer->up_so_far = 1;

  syslog(LOG_DEBUG, "printer_host_callback: printer %s queued %d-byte query",
	 printer->name, printer->buflen);

  free(pargs);
  return;

failure:
  if (s >= 0)
    close(s);
  printer->timer = timer_set_rel(60, printer_poll, pargs);
  return;
}
Exemplo n.º 17
0
TCPSTREAM *tcp_open (char *host,char *service,unsigned long port)
{
  TCPSTREAM *stream = NIL;
  int i,family;
  SOCKET sock = INVALID_SOCKET;
  int silent = (port & NET_SILENT) ? T : NIL;
  char *s,*hostname,tmp[MAILTMPLEN];
  void *adr,*next;
  size_t adrlen;
  struct servent *sv = NIL;
  blocknotify_t bn = (blocknotify_t) mail_parameters (NIL,GET_BLOCKNOTIFY,NIL);
  if (!wsa_initted++) {		/* init Windows Sockets */
    WSADATA wsock;
    if (i = (int) WSAStartup (WINSOCK_VERSION,&wsock)) {
      wsa_initted = 0;		/* in case we try again */
      sprintf (tmp,"Unable to start Windows Sockets (%d)",i);
      mm_log (tmp,ERROR);
      return NIL;
    }
  }
  port &= 0xffff;		/* erase flags */
				/* lookup service */
  if (service && (sv = getservbyname (service,"tcp")))
    port = ntohs (sv->s_port);
  /* The domain literal form is used (rather than simply the dotted decimal
     as with other Windows programs) because it has to be a valid "host name"
     in mailsystem terminology. */
				/* look like domain literal? */
  if (host[0] == '[' && host[(strlen (host))-1] == ']') {
    strcpy (tmp,host+1);	/* yes, copy number part */
    tmp[strlen (tmp)-1] = '\0';
    if (adr = ip_stringtoaddr (tmp,&adrlen,&family)) {
      (*bn) (BLOCK_TCPOPEN,NIL);
      sock = tcp_socket_open (family,adr,adrlen,(unsigned short) port,tmp,
			      hostname = host);
      (*bn) (BLOCK_NONE,NIL);
      fs_give ((void **) &adr);
    }
    else sprintf (tmp,"Bad format domain-literal: %.80s",host);
  }

  else {			/* lookup host name */
    if (tcpdebug) {
      sprintf (tmp,"DNS resolution %.80s",host);
      mm_log (tmp,TCPDEBUG);
    }
    (*bn) (BLOCK_DNSLOOKUP,NIL);/* look up name */
    if (!(s = ip_nametoaddr (host,&adrlen,&family,&hostname,&next)))
      sprintf (tmp,"Host not found (#%d): %s",WSAGetLastError (),host);
    (*bn) (BLOCK_NONE,NIL);
    if (s) {			/* DNS resolution won? */
      if (tcpdebug) mm_log ("DNS resolution done",TCPDEBUG);
      wsa_sock_open++;		/* prevent tcp_abort() from freeing in loop */
      do {
	(*bn) (BLOCK_TCPOPEN,NIL);
	if (((sock = tcp_socket_open (family,s,adrlen,(unsigned short) port,
				      tmp,hostname)) == INVALID_SOCKET) &&
	    (s = ip_nametoaddr (NIL,&adrlen,&family,&hostname,&next)) &&
	    !silent) mm_log (tmp,WARN);
	(*bn) (BLOCK_NONE,NIL);
      } while ((sock == INVALID_SOCKET) && s);
      wsa_sock_open--;		/* undo protection */
    }
  }
  if (sock == INVALID_SOCKET) {	/* do possible cleanup action */
    if (!silent) mm_log (tmp,ERROR);
    tcp_abort (&sock);	
  }
  else {			/* got a socket, create TCP/IP stream */
    stream = (TCPSTREAM *) memset (fs_get (sizeof (TCPSTREAM)),0,
				   sizeof (TCPSTREAM));
    stream->port = port;	/* port number */
				/* init socket */
    stream->tcpsi = stream->tcpso = sock;
    stream->ictr = 0;		/* init input counter */
				/* copy official host name */
    stream->host = cpystr (hostname);
    if (tcpdebug) mm_log ("Stream open and ready for read",TCPDEBUG);
  }
  return stream;		/* return success */
}
Exemplo n.º 18
0
int
getaddrinfo(char const *hostname, char const *servname,
	    struct addrinfo const *hints, struct addrinfo **res)
{
    struct addrinfo *cur, *prev = NULL;
    struct hostent *hp;
    struct hostent result;
    struct in_addr in;
    int i, socktype, proto;
    uint16_t port = 0;
    int error;
    char buffer[2048];

    if (hints && hints->ai_family != PF_INET && hints->ai_family != PF_UNSPEC)
	return EAI_FAMILY;

    socktype = (hints && hints->ai_socktype) ? hints->ai_socktype
					     : SOCK_STREAM;
    if (hints && hints->ai_protocol)
	proto = hints->ai_protocol;
    else {
	switch (socktype) {
	case SOCK_DGRAM:
	    proto = IPPROTO_UDP;
	    break;
	case SOCK_STREAM:
	    proto = IPPROTO_TCP;
	    break;
	default:
	    proto = 0;
	    break;
	}
    }
    if (servname) {
	if (isdigit((int)*servname))
	    port = htons(atoi(servname));
	else {
	    struct servent *se;
	    char const *pe_proto;

	    switch (socktype) {
	    case SOCK_DGRAM:
		pe_proto = "udp";
		break;
	    case SOCK_STREAM:
		pe_proto = "tcp";
		break;
	    default:
		pe_proto = NULL;
		break;
	    }
	    if ((se = getservbyname(servname, pe_proto)) == NULL)
		return EAI_SERVICE;
	    port = se->s_port;
	}
    }
    if (!hostname) {
	if (hints && hints->ai_flags & AI_PASSIVE)
	    *res = malloc_ai(port, htonl(0x00000000), socktype, proto);
	else
	    *res = malloc_ai(port, htonl(0x7f000001), socktype, proto);
	if (*res)
	    return 0;
	else
	    return EAI_MEMORY;
    }
    /* Numeric IP Address */
    if (inet_aton(hostname, &in)) {
	*res = malloc_ai(port, in.s_addr, socktype, proto);
	if (*res)
	    return 0;
	else
	    return EAI_MEMORY;
    }
    if (hints && hints->ai_flags & AI_NUMERICHOST)
	return EAI_NONAME;

    /* DNS Lookup */
#ifdef GETHOSTBYNAMERSTYLE
#if GETHOSTBYNAMERSTYLE == SYSVSTYLE
    hp = gethostbyname_r(hostname, &result, buffer, sizeof(buffer), &error);
#elif GETHOSTBYNAMERSTYLE == GNUSTYLE
    if (gethostbyname_r(hostname, &result, buffer,
	 sizeof(buffer), &hp, &error) != 0) {
		hp = NULL;
	}
#else
    hp = gethostbyname_r(hostname, &result, buffer, sizeof(buffer), &error);
#endif
#else
    hp = gethostbyname_r(hostname, &result, buffer, sizeof(buffer), &error);
#endif
    if (hp && hp->h_name && hp->h_name[0] && hp->h_addr_list[0]) {
	for (i = 0; hp->h_addr_list[i]; i++) {
	    if ((cur = malloc_ai(port,
				((struct in_addr *)hp->h_addr_list[i])->s_addr,
				socktype, proto)) == NULL) {
		if (*res)
		    freeaddrinfo(*res);
		return EAI_MEMORY;
	    }
	    if (prev)
		prev->ai_next = cur;
	    else
		*res = cur;
	    prev = cur;
	}
	if (hints && hints->ai_flags & AI_CANONNAME && *res) {
	    if (((*res)->ai_canonname = strdup(hp->h_name)) == NULL) {
		freeaddrinfo(*res);
		return EAI_MEMORY;
	    }
	}
	return 0;
    }
    return EAI_NONAME;
}
Exemplo n.º 19
0
R_API int r_socket_port_by_name(const char *name) {
	struct servent *p = getservbyname (name, "tcp");
	if (p && p->s_port)
		return ntohs (p->s_port);
	return r_num_get (NULL, name);
}
Exemplo n.º 20
0
int tcpopen(char *host,char *server)
{
int i,mflg=0;
int  s;
struct sockaddr_in sa;
struct hostent *hp=NULL;
struct servent *sp;
char addr[41],*cp;

	if((hp=gethostbyname(host))==NULL){
		if(isdigit(*host)){
		    cp=host;
		    i=0;
		    while(cp&&*cp&&i<4){
			addr[i]=strtol(cp,&cp,10);
			if(*cp=='.')cp++;
			i++;
		    }
		    if((hp=gethostbyaddr(addr,4,AF_INET))==NULL){
		        hp=(struct hostent *)malloc(sizeof(struct hostent));
			if(!hp) {
				return MEMERR;
			}
		        hp->h_name=strdup(host);
		        hp->h_aliases=0;
		        hp->h_addrtype=AF_INET;
		        hp->h_length=4;
		        hp->h_addr_list=(char **)malloc(sizeof(char *)*2);
		        hp->h_addr_list[0]=(char *)malloc(sizeof(char *)*8);
		        hp->h_addr_list[1]=0;
		        memcpy(hp->h_addr,addr,4);
			mflg=1;
		    }
		} else {
			ShowLog(1,"gethostbyname %s error",host);
			return(-2);
		}
	}
	if(!hp->h_addr) {
                if(mflg) {free(hp->h_name);
                	free(hp->h_addr_list[0]);
          		free(hp->h_addr_list);
			free(hp);
		}
		return FORMATERR;
	}
	bcopy((char *)hp->h_addr,(char *)&sa.sin_addr,hp->h_length);
	sa.sin_family=hp->h_addrtype;
    	if(isdigit(server[0])){
	    sa.sin_port=htons((u_short)atol(server));
    	} else {
	    if((sp=getservbyname(server,"tcp"))==NULL){
                if(mflg) {free(hp->h_name);
                	free(hp->h_addr_list[0]);
          		free(hp->h_addr_list);
			free(hp);
		}
		ShowLog(1,"getsrvbyname %s error",server);
		return(-3);
	    }
	    sa.sin_port=(u_short)sp->s_port;
	}
	if((s=socket(hp->h_addrtype,SOCK_STREAM,0))<=0){
		i=errno;
                if(mflg) {free(hp->h_name);
                	free(hp->h_addr_list[0]);
          		free(hp->h_addr_list);
			free(hp);
		}
		ShowLog(1,"tcpopen socket error %d,%s",errno,strerror(errno));
		return -4;
	}
        if(mflg) {free(hp->h_name);
              	free(hp->h_addr_list[0]);
        	free(hp->h_addr_list);
		free(hp);
	}
/* 如果要已经处于连接状态的soket在调用closesocket后强制关闭,不经历TIME_WAIT的过程:
BOOL bDontLinger = FALSE;
setsockopt(s,SOL_SOCKET,SO_DONTLINGER,(const char*)&bDontLinger,sizeof(BOOL));
for WINDOWS */

#ifdef LINUX
	i=1;
	setsockopt(s,SOL_SOCKET,SO_REUSEADDR,&i,sizeof(i));
#endif
	if((int)connect(s,(struct sockaddr *)&sa,sizeof(sa))< 0){
		ShowLog(1,"connect %s/%s  error %d",host,server,errno);
		i=errno;
		close(s);
		s=-1;
		errno=i;
	}
	return(s);
}
Exemplo n.º 21
0
/*
 * A. Shawn Bandy
 * CECS 472
 * Assignment 4
 * 09/11/2012
*/
#include <sys/types.h> /* u_long */
#include <netdb.h> /* getXbyY */
#include <netinet/in.h> /*htons*/
#include <stdio.h> /*printf*/
#include <string.h> /*memcpy*/
#include <arpa/inet.h> /*inet_ntoa*/
int main(int argc, char *argv[])
{
    struct hostent *hp;
    struct servent *sp, *sp2;
    struct in_addr addr;
    printf("--Info--\n");
    if(argc == 5) {
        //ARGUMENT 1
        hp = gethostbyname(argv[1]);
        if(hp) {
            memcpy(&addr, hp->h_addr, hp->h_length);
            printf("Hostname from %s:  %s\n",argv[1],inet_ntoa(addr));
        } else {
            printf("ERROR: gethostbyname failed on %s\n",argv[1]);
        }

        //ARGUMENT 2
        sp = getservbyname(argv[2],"tcp");
        if(sp) {
            printf("Port number from service name %s: %i\n",argv[2],ntohs(sp->s_port));
        } else {
            printf("ERROR: getservicebyname failed on %s\n",argv[2]);
        }

        //ARGUMENT 3
        sp2 = getservbyport(htons(atoi(argv[3])),"tcp");
        if(sp2) {
            printf("Service name from port %s: %s\n",argv[3],sp2->s_name);
        } else {
            printf("ERROR: getservbyport failed on %s\n",argv[3]);
        }
        //ARGUMENT 4
        if(inet_addr(argv[4]) != INADDR_NONE) {
            printf("Internet address of %s: %i\n",argv[4],inet_addr(argv[4]));
        } else {
            printf("ERROR: inet_addr failed on %s\n",argv[4]);
        }
    } else {
        printf("ERROR: Wrong number of arguments.");
    }
    printf("--/Info--\n");
    /*
    struct hostent *hp, *hp2;
    struct in_addr addr;

    hp = gethostbyname("cheetah.cecs.csulb.edu");
    printf("%s\n",hp->h_name);
    printf("%d\n",hp->h_length);
    memcpy(&addr, hp->h_addr, hp->h_length);
    printf("%x\n",ntohl(addr.s_addr));
    printf("%s\n",inet_ntoa(addr));
    hp2 = gethostbyaddr(&addr, 4, AF_INET);

    {
    struct servent *sp, *sp2;
    sp = getservbyname("telnet", "tcp");
    printf("%s\n",sp->s_name); // telnet
    printf("%d\n",ntohs(sp->s_port)); // 23
    printf("%s\n",sp->s_proto); // tcp
    sp2 = getservbyport(htons(23), "tcp");
    */

    return 0;
};
Exemplo n.º 22
0
int
main(int argc, char **argv)
{
#ifdef __FreeBSD__
	FILE		*fpid = NULL;
#endif	
	int		 ch;
	struct passwd	*pw;
	pcap_handler	 phandler = logpkt_handler;
	int syncfd = 0;
	struct servent *ent;
	char *sync_iface = NULL;
	char *sync_baddr = NULL;

	if ((ent = getservbyname("spamd-sync", "udp")) == NULL)
		errx(1, "Can't find service \"spamd-sync\" in /etc/services");
	sync_port = ntohs(ent->s_port);
#ifndef __FreeBSD__
	while ((ch = getopt(argc, argv, "DIi:l:Y:")) != -1) {
#else
	while ((ch = getopt(argc, argv, "DIi:l:Y:m:")) != -1) {
#endif
		switch (ch) {
		case 'D':
			flag_debug = 1;
			break;
		case 'I':
			flag_inbound = 1;
			break;
		case 'i':
			networkif = optarg;
			break;
		case 'l':
			pflogif = optarg;
			break;
		case 'Y':
			if (sync_addhost(optarg, sync_port) != 0)
				sync_iface = optarg;
			syncsend++;
			break;
#ifdef __FreeBSD__
		case 'm':
			if (strcmp(optarg, "ipfw") == 0)
				use_pf=0;
			break;
#endif
			
		default:
			usage();
			/* NOTREACHED */
		}
	}

	signal(SIGINT , sighandler_close);
	signal(SIGQUIT, sighandler_close);
	signal(SIGTERM, sighandler_close);

	logmsg(LOG_DEBUG, "Listening on %s for %s %s", pflogif,
	    (networkif == NULL) ? "all interfaces." : networkif,
	    (flag_inbound) ? "Inbound direction only." : "");

	if (init_pcap() == -1)
		err(1, "couldn't initialize pcap");

	if (syncsend) {
		syncfd = sync_init(sync_iface, sync_baddr, sync_port);
		if (syncfd == -1)
			err(1, "sync init");
	}
	
#ifdef __FreeBSD__
	/* open the pid file just before switch the user */
	fpid = fopen(pid_file, "w");
	if (fpid == NULL) {
		syslog(LOG_ERR, "exiting (couldn't create pid file %s)", 
				pid_file);
		 err(1, "couldn't create pid file \"%s\"", pid_file);
	}
#endif	

	/* privdrop */
	pw = getpwnam("_spamd");
	if (pw == NULL)
		errx(1, "User '_spamd' not found! ");

	if (setgroups(1, &pw->pw_gid) ||
	    setresgid(pw->pw_gid, pw->pw_gid, pw->pw_gid) ||
	    setresuid(pw->pw_uid, pw->pw_uid, pw->pw_uid))
		err(1, "failed to drop privs");

	if (!flag_debug) {
		if (daemon(0, 0) == -1)
			err(1, "daemon");
		tzset();
		openlog_r("spamlogd", LOG_PID | LOG_NDELAY, LOG_DAEMON, &sdata);
	}

#ifdef __FreeBSD__
	/* after switch user and daemon write and close the pid file */
	if (fpid) {
		fprintf(fpid, "%ld\n", (long) getpid());
		if (fclose(fpid) == EOF) {
			syslog(LOG_ERR, "exiting (couldn't close pid file %s)", 
				pid_file);
			exit (1);
		}
	}
#endif	

	pcap_loop(hpcap, -1, phandler, NULL);

	logmsg(LOG_NOTICE, "exiting");
	if (!flag_debug)
		closelog_r(&sdata);

	exit(0);
}
Exemplo n.º 23
0
static void MailResult(const ExecConfig *config, const char *file)
{
#if defined __linux__ || defined __NetBSD__ || defined __FreeBSD__ || defined __OpenBSD__
    time_t now = time(NULL);
#endif
    Log(LOG_LEVEL_VERBOSE, "Mail result...");

    {
        struct stat statbuf;
        if (stat(file, &statbuf) == -1)
        {
            return;
        }

        if (statbuf.st_size == 0)
        {
            unlink(file);
            Log(LOG_LEVEL_DEBUG, "Nothing to report in file '%s'", file);
            return;
        }
    }

    {
        char prev_file[CF_BUFSIZE];
        snprintf(prev_file, CF_BUFSIZE - 1, "%s/outputs/previous", CFWORKDIR);
        MapName(prev_file);

        if (CompareResult(file, prev_file) == 0)
        {
            Log(LOG_LEVEL_VERBOSE, "Previous output is the same as current so do not mail it");
            return;
        }
    }

    if ((strlen(config->mail_server) == 0) || (strlen(config->mail_to_address) == 0))
    {
        /* Syslog should have done this */
        Log(LOG_LEVEL_VERBOSE, "Empty mail server or address - skipping");
        return;
    }

    if (config->mail_max_lines == 0)
    {
        Log(LOG_LEVEL_DEBUG, "Not mailing: EmailMaxLines was zero");
        return;
    }

    Log(LOG_LEVEL_DEBUG, "Mailing results of '%s' to '%s'", file, config->mail_to_address);

/* Check first for anomalies - for subject header */

    FILE *fp = fopen(file, "r");
    if (!fp)
    {
        Log(LOG_LEVEL_INFO, "Couldn't open file '%s'. (fopen: %s)", file, GetErrorStr());
        return;
    }

    bool anomaly = false;
    char vbuff[CF_BUFSIZE];

    while (!feof(fp))
    {
        vbuff[0] = '\0';
        if (fgets(vbuff, sizeof(vbuff), fp) == NULL)
        {
            break;
        }

        if (strstr(vbuff, "entropy"))
        {
            anomaly = true;
            break;
        }
    }

    fclose(fp);

    if ((fp = fopen(file, "r")) == NULL)
    {
        Log(LOG_LEVEL_INFO, "Couldn't open file '%s'. (fopen: %s)", file, GetErrorStr());
        return;
    }

    struct hostent *hp = gethostbyname(config->mail_server);
    if (!hp)
    {
        Log(LOG_LEVEL_ERR, "While mailing agent output, unknown host '%s'. Make sure that fully qualified names can be looked up at your site.",
            config->mail_server);
        fclose(fp);
        return;
    }

    struct servent *server = getservbyname("smtp", "tcp");
    if (!server)
    {
        Log(LOG_LEVEL_INFO, "Unable to lookup smtp service. (getservbyname: %s)", GetErrorStr());
        fclose(fp);
        return;
    }

    struct sockaddr_in raddr;
    memset(&raddr, 0, sizeof(raddr));

    raddr.sin_port = (unsigned int) server->s_port;
    raddr.sin_addr.s_addr = ((struct in_addr *) (hp->h_addr))->s_addr;
    raddr.sin_family = AF_INET;

    Log(LOG_LEVEL_DEBUG, "Connecting...");

    int sd = socket(AF_INET, SOCK_STREAM, 0);
    if (sd == -1)
    {
        Log(LOG_LEVEL_INFO, "Couldn't open a socket. (socket: %s)", GetErrorStr());
        fclose(fp);
        return;
    }

    if (connect(sd, (void *) &raddr, sizeof(raddr)) == -1)
    {
        Log(LOG_LEVEL_INFO, "Couldn't connect to host '%s'. (connect: %s)",
            config->mail_server, GetErrorStr());
        fclose(fp);
        cf_closesocket(sd);
        return;
    }

/* read greeting */

    if (!Dialogue(sd, NULL))
    {
        goto mail_err;
    }

    sprintf(vbuff, "HELO %s\r\n", config->fq_name);
    Log(LOG_LEVEL_DEBUG, "%s", vbuff);

    if (!Dialogue(sd, vbuff))
    {
        goto mail_err;
    }

    if (strlen(config->mail_from_address) == 0)
    {
        sprintf(vbuff, "MAIL FROM: <cfengine@%s>\r\n", config->fq_name);
        Log(LOG_LEVEL_DEBUG, "%s", vbuff);
    }
    else
    {
        sprintf(vbuff, "MAIL FROM: <%s>\r\n", config->mail_from_address);
        Log(LOG_LEVEL_DEBUG, "%s", vbuff);
    }

    if (!Dialogue(sd, vbuff))
    {
        goto mail_err;
    }

    sprintf(vbuff, "RCPT TO: <%s>\r\n", config->mail_to_address);
    Log(LOG_LEVEL_DEBUG, "%s", vbuff);

    if (!Dialogue(sd, vbuff))
    {
        goto mail_err;
    }

    if (!Dialogue(sd, "DATA\r\n"))
    {
        goto mail_err;
    }

    char mailsubject_anomaly_prefix[8];
    if (anomaly)
    {
        strcpy(mailsubject_anomaly_prefix, "**!! ");
    }
    else
    {
        mailsubject_anomaly_prefix[0] = '\0';
    }

    if (SafeStringLength(config->mail_subject) == 0)
    {
        snprintf(vbuff, sizeof(vbuff), "Subject: %s[%s/%s]\r\n", mailsubject_anomaly_prefix, config->fq_name, config->ip_address);
        Log(LOG_LEVEL_DEBUG, "%s", vbuff);
    }
    else
    {
        snprintf(vbuff, sizeof(vbuff), "Subject: %s%s\r\n", mailsubject_anomaly_prefix, config->mail_subject);
        Log(LOG_LEVEL_DEBUG, "%s", vbuff);
    }

    send(sd, vbuff, strlen(vbuff), 0);

    /* send X-CFEngine SMTP header if mailsubject set */
    if (SafeStringLength(config->mail_subject) > 0)
    {
        unsigned char digest[EVP_MAX_MD_SIZE + 1];
        char buffer[EVP_MAX_MD_SIZE * 4];

        char *existing_policy_server = ReadPolicyServerFile(GetWorkDir());

        HashPubKey(PUBKEY, digest, CF_DEFAULT_DIGEST);

        snprintf(vbuff, sizeof(vbuff), "X-CFEngine: vfqhost=\"%s\";ip-addresses=\"%s\";policyhub=\"%s\";pkhash=\"%s\"\r\n",
                 VFQNAME, config->ip_addresses, existing_policy_server,
                 HashPrintSafe(CF_DEFAULT_DIGEST, true, digest, buffer));

        send(sd, vbuff, strlen(vbuff), 0);
        free(existing_policy_server);
    }

#if defined __linux__ || defined __NetBSD__ || defined __FreeBSD__ || defined __OpenBSD__
    strftime(vbuff, CF_BUFSIZE, "Date: %a, %d %b %Y %H:%M:%S %z\r\n", localtime(&now));
    send(sd, vbuff, strlen(vbuff), 0);
#endif

    if (strlen(config->mail_from_address) == 0)
    {
        sprintf(vbuff, "From: cfengine@%s\r\n", config->fq_name);
        Log(LOG_LEVEL_DEBUG, "%s", vbuff);
    }
    else
    {
        sprintf(vbuff, "From: %s\r\n", config->mail_from_address);
        Log(LOG_LEVEL_DEBUG, "%s", vbuff);
    }

    send(sd, vbuff, strlen(vbuff), 0);

    sprintf(vbuff, "To: %s\r\n\r\n", config->mail_to_address);
    Log(LOG_LEVEL_DEBUG, "%s", vbuff);
    send(sd, vbuff, strlen(vbuff), 0);

    int count = 0;
    while (!feof(fp))
    {
        vbuff[0] = '\0';
        if (fgets(vbuff, sizeof(vbuff), fp) == NULL)
        {
            break;
        }

        Log(LOG_LEVEL_DEBUG, "%s", vbuff);

        if (strlen(vbuff) > 0)
        {
            vbuff[strlen(vbuff) - 1] = '\r';
            strcat(vbuff, "\n");
            count++;
            send(sd, vbuff, strlen(vbuff), 0);
        }

        if ((config->mail_max_lines != INF_LINES) && (count > config->mail_max_lines))
        {
            sprintf(vbuff, "\r\n[Mail truncated by cfengine. File is at %s on %s]\r\n", file, config->fq_name);
            send(sd, vbuff, strlen(vbuff), 0);
            break;
        }
    }

    if (!Dialogue(sd, ".\r\n"))
    {
        Log(LOG_LEVEL_DEBUG, "mail_err\n");
        goto mail_err;
    }

    Dialogue(sd, "QUIT\r\n");
    Log(LOG_LEVEL_DEBUG, "Done sending mail");
    fclose(fp);
    cf_closesocket(sd);
    return;

  mail_err:

    fclose(fp);
    cf_closesocket(sd);
    Log(LOG_LEVEL_INFO, "Cannot mail to %s.", config->mail_to_address);
}
Exemplo n.º 24
0
int
main(int argc, char *argv[])
{
	struct sockaddr_in from;
	struct stat st;
	char path[64];
	int on = 1;
	char *cp;
	struct sockaddr_in soin;
	uid_t unpriv_uid;
	gid_t unpriv_gid;

	if (getuid())
		errx(1, "not super user");

	run_as(&unpriv_uid, &unpriv_gid);

	argv++; argc--;
	while (argc > 0 && *argv[0] == '-') {
		if (strcmp(*argv, "-m") == 0) {
			if (argc > 1 && isdigit(*(argv + 1)[0])) {
				argv++, argc--;
				multicast_mode  = SCOPED_MULTICAST;
				multicast_scope = atoi(*argv);
				if (multicast_scope > MAX_MULTICAST_SCOPE)
					errx(1, "ttl must not exceed %u",
					MAX_MULTICAST_SCOPE);
			}
			else multicast_mode = PER_INTERFACE_MULTICAST;
		}
		else if (strcmp(*argv, "-i") == 0)
			insecure_mode = 1;
		else if (strcmp(*argv, "-l") == 0)
			quiet_mode = 1;
		else if (strcmp(*argv, "-p") == 0)
			iff_flag = 0;
		else
			usage();
		argv++, argc--;
	}
	if (argc > 0)
		usage();
#ifndef DEBUG
	daemon(1, 0);
#endif
	(void) signal(SIGHUP, getboottime);
	openlog("rwhod", LOG_PID, LOG_DAEMON);
	sp = getservbyname("who", "udp");
	if (sp == NULL) {
		syslog(LOG_ERR, "who/udp: unknown service");
		exit(1);
	}
	if (chdir(_PATH_RWHODIR) < 0) {
		syslog(LOG_ERR, "%s: %m", _PATH_RWHODIR);
		exit(1);
	}
	/*
	 * Establish host name as returned by system.
	 */
	if (gethostname(myname, sizeof(myname) - 1) < 0) {
		syslog(LOG_ERR, "gethostname: %m");
		exit(1);
	}
	if ((cp = index(myname, '.')) != NULL)
		*cp = '\0';
	strncpy(mywd.wd_hostname, myname, sizeof(mywd.wd_hostname) - 1);
	mywd.wd_hostname[sizeof(mywd.wd_hostname) - 1] = '\0';
#ifdef __APPLE__
	utmpf = open(_PATH_UTMPX, O_RDONLY|O_CREAT, 0644);
#else
	utmpf = open(_PATH_UTMP, O_RDONLY|O_CREAT, 0644);
#endif
	if (utmpf < 0) {
#ifdef __APPLE__
		syslog(LOG_ERR, "%s: %m", _PATH_UTMPX);
#else
		syslog(LOG_ERR, "%s: %m", _PATH_UTMP);
#endif
		exit(1);
	}
	getboottime(0);
	if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
		syslog(LOG_ERR, "socket: %m");
		exit(1);
	}
	if (setsockopt(s, SOL_SOCKET, SO_BROADCAST, &on, sizeof(on)) < 0) {
		syslog(LOG_ERR, "setsockopt SO_BROADCAST: %m");
		exit(1);
	}
	memset(&soin, 0, sizeof(soin));
	soin.sin_len = sizeof(soin);
	soin.sin_family = AF_INET;
	soin.sin_port = sp->s_port;
	if (bind(s, (struct sockaddr *)&soin, sizeof(soin)) < 0) {
		syslog(LOG_ERR, "bind: %m");
		exit(1);
	}
	setgid(unpriv_gid);
	setgroups(1, &unpriv_gid);	/* XXX BOGUS groups[0] = egid */
	setuid(unpriv_uid);
	if (!configure(s))
		exit(1);
	if (!quiet_mode) {
		signal(SIGALRM, onalrm);
		onalrm(0);
	}
	for (;;) {
		struct whod wd;
		socklen_t len = sizeof(from);
		int cc, whod;
		time_t t;

		cc = recvfrom(s, (char *)&wd, sizeof(struct whod), 0,
			(struct sockaddr *)&from, &len);
		if (cc <= 0) {
			if (cc < 0 && errno != EINTR)
				syslog(LOG_WARNING, "recv: %m");
			continue;
		}
		if (from.sin_port != sp->s_port && !insecure_mode) {
			syslog(LOG_WARNING, "%d: bad source port from %s",
			    ntohs(from.sin_port), inet_ntoa(from.sin_addr));
			continue;
		}
		if (cc < WHDRSIZE) {
			syslog(LOG_WARNING, "short packet from %s",
			    inet_ntoa(from.sin_addr));
			continue;
		}
		if (wd.wd_vers != WHODVERSION)
			continue;
		if (wd.wd_type != WHODTYPE_STATUS)
			continue;
		if (!verify(wd.wd_hostname, sizeof wd.wd_hostname)) {
			syslog(LOG_WARNING, "malformed host name from %s",
			    inet_ntoa(from.sin_addr));
			continue;
		}
		(void) snprintf(path, sizeof path, "whod.%s", wd.wd_hostname);
		/*
		 * Rather than truncating and growing the file each time,
		 * use ftruncate if size is less than previous size.
		 */
		whod = open(path, O_WRONLY | O_CREAT, 0644);
		if (whod < 0) {
			syslog(LOG_WARNING, "%s: %m", path);
			continue;
		}
#if ENDIAN != BIG_ENDIAN
		{
			int i, n = (cc - WHDRSIZE)/sizeof(struct whoent);
			struct whoent *we;

			/* undo header byte swapping before writing to file */
			wd.wd_sendtime = ntohl(wd.wd_sendtime);
			for (i = 0; i < 3; i++)
				wd.wd_loadav[i] = ntohl(wd.wd_loadav[i]);
			wd.wd_boottime = ntohl(wd.wd_boottime);
			we = wd.wd_we;
			for (i = 0; i < n; i++) {
				we->we_idle = ntohl(we->we_idle);
				we->we_utmp.out_time =
				    ntohl(we->we_utmp.out_time);
				we++;
			}
		}
#endif
		(void) time(&t);
		wd.wd_recvtime = _time_to_int(t);
		(void) write(whod, (char *)&wd, cc);
		if (fstat(whod, &st) < 0 || st.st_size > cc)
			ftruncate(whod, cc);
		(void) close(whod);
	}
}
Exemplo n.º 25
0
int NetInit()
{
int s;
struct servent *servent;
char *udp_device;
char *tcp_device;
nwio_udpopt_t udpopt;
nwio_tcpconf_t tcpconf;

   if((udp_device = getenv("UDP_DEVICE")) == (char *)NULL)
   	udp_device = UDP_DEVICE;

   if((udp_ctl = open(udp_device, O_RDWR)) < 0) {
   	fprintf(stderr, "talk: Could not open %s: %s\n",
   		udp_device, strerror(errno));
   	return(-1);
   }

   if((servent = getservbyname("ntalk", "udp")) == (struct servent *)NULL) {
   	fprintf(stderr, "talk: Could not find ntalk udp service\n");
   	close(udp_ctl);
   	return(-1);
   }

   ntalk_port = (udpport_t)servent->s_port;

   udpopt.nwuo_flags = NWUO_NOFLAGS;
   udpopt.nwuo_flags |= NWUO_COPY | NWUO_LP_SEL | NWUO_EN_LOC;
   udpopt.nwuo_flags |= NWUO_DI_BROAD | NWUO_RP_SET | NWUO_RA_SET;
   udpopt.nwuo_flags |= NWUO_RWDATONLY | NWUO_DI_IPOPT;
   udpopt.nwuo_remaddr = raddr;
   udpopt.nwuo_remport = ntalk_port;

   s = ioctl(udp_ctl, NWIOSUDPOPT, &udpopt);
   if(s < 0) {
   	perror("talk: ioctl NWIOSUDPOPT");
   	close(udp_ctl);
   	return(-1);
   }

   s = ioctl(udp_ctl, NWIOGUDPOPT, &udpopt);
   if(s < 0) {
   	perror("talk: ioctl NWIOGUDPOPT");
   	close(udp_ctl);
   	return(-1);
   }
   laddr = udpopt.nwuo_locaddr;
   ctlport = udpopt.nwuo_locport;

   if((tcp_device = getenv("TCP_DEVICE")) == (char *)NULL)
   	tcp_device = TCP_DEVICE;

   if((tcp_fd = open(tcp_device, O_RDWR)) < 0) {
   	fprintf(stderr, "talk: Could not open %s: %s\n",
   		tcp_device, strerror(errno));
   	close(udp_ctl);
   	return(-1);
   }

   tcpconf.nwtc_flags = NWTC_NOFLAGS;
   tcpconf.nwtc_flags |= NWTC_LP_SEL | NWTC_SET_RA | NWTC_UNSET_RP;
   tcpconf.nwtc_remaddr = raddr;

   s = ioctl(tcp_fd, NWIOSTCPCONF, &tcpconf);
   if(s < 0) {
   	perror("talk: ioctl NWIOSTCPCONF");
   	close(udp_ctl);
   	close(tcp_fd);
   	return(-1);
   }

   s = ioctl(tcp_fd, NWIOGTCPCONF, &tcpconf);
   if(s < 0) {
   	perror("talk: ioctl NWIOGTCPCONF");
   	close(udp_ctl);
   	close(tcp_fd);
   	return(-1);
   }

   dataport = tcpconf.nwtc_locport;

   return(0);
}
Exemplo n.º 26
0
static int
smux_socket (void)
{
    int ret;
#ifdef HAVE_IPV6
    struct addrinfo hints, *res0, *res;
    int gai;
#else
    struct sockaddr_in serv;
    struct servent *sp;
#endif
    int sock = 0;

#ifdef HAVE_IPV6
    memset(&hints, 0, sizeof(hints));
    hints.ai_family = PF_UNSPEC;
    hints.ai_socktype = SOCK_STREAM;
    gai = getaddrinfo(NULL, "smux", &hints, &res0);
    if (gai == EAI_SERVICE)
    {
        char servbuf[NI_MAXSERV];
        sprintf(servbuf,"%d",SMUX_PORT_DEFAULT);
        servbuf[sizeof (servbuf) - 1] = '\0';
        gai = getaddrinfo(NULL, servbuf, &hints, &res0);
    }
    if (gai)
    {
        zlog_warn("Cannot locate loopback service smux");
        return -1;
    }
    for(res=res0; res; res=res->ai_next)
    {
        if (res->ai_family != AF_INET
#ifdef HAVE_IPV6
                && res->ai_family != AF_INET6
#endif /* HAVE_IPV6 */
           )
            continue;

        sock = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
        if (sock < 0)
            continue;
        sockopt_reuseaddr (sock);
        sockopt_reuseport (sock);
        ret = connect (sock, res->ai_addr, res->ai_addrlen);
        if (ret < 0)
        {
            close(sock);
            sock = -1;
            continue;
        }
        break;
    }
    freeaddrinfo(res0);
    if (sock < 0 && debug_smux)
        zlog_warn ("Can't connect to SNMP agent with SMUX");
#else
    sock = socket (AF_INET, SOCK_STREAM, 0);
    if (sock < 0)
    {
        zlog_warn ("Can't make socket for SNMP");
        return -1;
    }

    memset (&serv, 0, sizeof (struct sockaddr_in));
    serv.sin_family = AF_INET;
#ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
    serv.sin_len = sizeof (struct sockaddr_in);
#endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */

    sp = getservbyname ("smux", "tcp");
    if (sp != NULL)
        serv.sin_port = sp->s_port;
    else
        serv.sin_port = htons (SMUX_PORT_DEFAULT);

    serv.sin_addr.s_addr = htonl (INADDR_LOOPBACK);

    sockopt_reuseaddr (sock);
    sockopt_reuseport (sock);

    ret = connect (sock, (struct sockaddr *) &serv, sizeof (struct sockaddr_in));
    if (ret < 0)
    {
        close (sock);
        smux_sock = -1;
        if (debug_smux)
            zlog_warn ("Can't connect to SNMP agent with SMUX");
        return -1;
    }
#endif
    return sock;
}
Exemplo n.º 27
0
/*
 * init:
 *	Initialize the global parameters.
 */
static void
init(void)
{
	int	i;
	struct sockaddr_in	test_port;
	int	true = 1;
	socklen_t	len;
	struct sockaddr_in	addr;
	struct sigaction	sact;
	struct servent *se;

	(void) setsid();
	if (setpgid(getpid(), getpid()) == -1)
		err(1, "setpgid");

	sact.sa_flags = SA_RESTART;
	sigemptyset(&sact.sa_mask);

	/* Ignore HUP, QUIT and PIPE: */
	sact.sa_handler = SIG_IGN;
	if (sigaction(SIGHUP, &sact, NULL) == -1)
		err(1, "sigaction SIGHUP");
	if (sigaction(SIGQUIT, &sact, NULL) == -1)
		err(1, "sigaction SIGQUIT");
	if (sigaction(SIGPIPE, &sact, NULL) == -1)
		err(1, "sigaction SIGPIPE");

	/* Clean up gracefully on INT and TERM: */
	sact.sa_handler = cleanup;
	if (sigaction(SIGINT, &sact, NULL) == -1)
		err(1, "sigaction SIGINT");
	if (sigaction(SIGTERM, &sact, NULL) == -1)
		err(1, "sigaction SIGTERM");

	/* Handle INFO: */
	sact.sa_handler = siginfo;
	if (sigaction(SIGINFO, &sact, NULL) == -1)
		err(1, "sigaction SIGINFO");

	if (chdir("/") == -1)
		warn("chdir");
	(void) umask(0777);

	/* Initialize statistics socket: */
	addr.sin_family = AF_INET;
	addr.sin_addr.s_addr = Server_addr;
	addr.sin_port = 0;

	Status = socket(AF_INET, SOCK_STREAM, 0);
	if (bind(Status, (struct sockaddr *) &addr, sizeof addr) < 0) {
		logit(LOG_ERR, "bind");
		cleanup(1);
	}
	if (listen(Status, 5) == -1) {
		logit(LOG_ERR, "listen");
		cleanup(1);
	}

	len = sizeof (struct sockaddr_in);
	if (getsockname(Status, (struct sockaddr *) &addr, &len) < 0)  {
		logit(LOG_ERR, "getsockname");
		cleanup(1);
	}
	stat_port = ntohs(addr.sin_port);

	/* Initialize main socket: */
	addr.sin_family = AF_INET;
	addr.sin_addr.s_addr = Server_addr;
	addr.sin_port = 0;

	Socket = socket(AF_INET, SOCK_STREAM, 0);

	if (bind(Socket, (struct sockaddr *) &addr, sizeof addr) < 0) {
		logit(LOG_ERR, "bind");
		cleanup(1);
	}
	if (listen(Socket, 5) == -1) {
		logit(LOG_ERR, "listen");
		cleanup(1);
	}

	len = sizeof (struct sockaddr_in);
	if (getsockname(Socket, (struct sockaddr *) &addr, &len) < 0)  {
		logit(LOG_ERR, "getsockname");
		cleanup(1);
	}
	sock_port = ntohs(addr.sin_port);

	/* Initialize minimal select mask */
	FD_ZERO(&Fds_mask);
	FD_SET(Socket, &Fds_mask);
	FD_SET(Status, &Fds_mask);
	Num_fds = ((Socket > Status) ? Socket : Status) + 1;

	/* Find the port that huntd should run on */
	if (Server_port == 0) {
		se = getservbyname("hunt", "udp");
		if (se != NULL)
			Server_port = ntohs(se->s_port);
		else
			Server_port = HUNT_PORT;
	}

	/* Check if stdin is a socket: */
	len = sizeof (struct sockaddr_in);
	if (getsockname(STDIN_FILENO, (struct sockaddr *) &test_port, &len) >= 0
	    && test_port.sin_family == AF_INET) {
		/* We are probably running from inetd:  don't log to stderr */
		Server_socket = STDIN_FILENO;
		conf_logerr = 0;
		if (test_port.sin_port != htons((u_short) Server_port)) {
			/* Private game */
			should_announce = FALSE;
			Server_port = ntohs(test_port.sin_port);
		}
	} else {
		/* We need to listen on a socket: */
		test_port = addr;
		test_port.sin_port = htons((u_short) Server_port);

		Server_socket = socket(AF_INET, SOCK_DGRAM, 0);

		/* Permit multiple huntd's on the same port. */
		if (setsockopt(Server_socket, SOL_SOCKET, SO_REUSEPORT, &true,
		    sizeof true) < 0)
			logit(LOG_ERR, "setsockopt SO_REUSEADDR");

		if (bind(Server_socket, (struct sockaddr *) &test_port,
		    sizeof test_port) < 0) {
			logit(LOG_ERR, "bind port %d", Server_port);
			cleanup(1);
		}

		/* Datagram sockets do not need a listen() call. */
	}

	/* We'll handle the broadcast listener in the main loop: */
	FD_SET(Server_socket, &Fds_mask);
	if (Server_socket + 1 > Num_fds)
		Num_fds = Server_socket + 1;

	/* Initialise the random seed: */
	srandomdev();

	/* Dig the maze: */
	makemaze();

	/* Create some boots, if needed: */
	makeboots();

	/* Construct a table of what objects a player can see over: */
	for (i = 0; i < NASCII; i++)
		See_over[i] = TRUE;
	See_over[DOOR] = FALSE;
	See_over[WALL1] = FALSE;
	See_over[WALL2] = FALSE;
	See_over[WALL3] = FALSE;
	See_over[WALL4] = FALSE;
	See_over[WALL5] = FALSE;

	logx(LOG_INFO, "game started");
}
Exemplo n.º 28
0
int main(int argc, char **argv)
{
	int i;
	struct servent *service;
	udpport_t route_port;
	nwio_udpopt_t udpopt;
	nwio_ipopt_t ipopt;
	asynchio_t asyn;
	time_t timeout;
	struct timeval tv;
	struct sigaction sa;
	char *offset_arg, *offset_end;
	long arg;

	udp_device= ip_device= nil;
	offset_arg= nil;

	for (i = 1; i < argc && argv[i][0] == '-'; i++) {
		char *p= argv[i] + 1;

		if (p[0] == '-' && p[1] == 0) { i++; break; }

		while (*p != 0) {
			switch (*p++) {
			case 'U':
				if (udp_device != nil) usage();
				if (*p == 0) {
					if (++i == argc) usage();
					p= argv[i];
				}
				udp_device= p;
				p= "";
				break;
			case 'I':
				if (ip_device != nil) usage();
				if (*p == 0) {
					if (++i == argc) usage();
					p= argv[i];
				}
				ip_device= p;
				p= "";
				break;
			case 'o':
				if (offset_arg != nil) usage();
				if (*p == 0) {
					if (++i == argc) usage();
					p= argv[i];
				}
				offset_arg= p;
				p= "";
				break;
			case 'b':
				bcast= 1;
				break;
			case 's':
				/*obsolete*/
				break;
			case 'd':
				debug= 1;
				break;
			default:
				usage();
			}
		}
	}
	if (i != argc) usage();

	/* Debug level signals. */
	sa.sa_handler= sig_handler;
	sigemptyset(&sa.sa_mask);
	sa.sa_flags= 0;
	sigaction(SIGUSR1, &sa, nil);
	sigaction(SIGUSR2, &sa, nil);

	if (udp_device == nil && (udp_device= getenv("UDP_DEVICE")) == nil)
		udp_device= UDP_DEVICE;

	if (ip_device == nil && (ip_device= getenv("IP_DEVICE")) == nil)
		ip_device= IP_DEVICE;

	if (offset_arg == nil) {
		priority_offset= PRIO_OFF_DEF;
	} else {
		arg= strtol(offset_arg, &offset_end, 0);
		if (*offset_end != 0 || (priority_offset= arg) != arg) usage();
	}

	if ((service= getservbyname("route", "udp")) == nil) {
		fprintf(stderr,
	"irdpd: unable to look up the port number for the 'route' service\n");
		exit(1);
	}

	route_port= (udpport_t) service->s_port;

	if ((rip_fd= open(udp_device, O_RDWR)) < 0) fatal(udp_device);

	udpopt.nwuo_flags= NWUO_COPY | NWUO_LP_SET | NWUO_DI_LOC
		| NWUO_EN_BROAD | NWUO_RP_SET | NWUO_RA_ANY | NWUO_RWDATALL
		| NWUO_DI_IPOPT;
	udpopt.nwuo_locport= route_port;
	udpopt.nwuo_remport= route_port;
	if (ioctl(rip_fd, NWIOSUDPOPT, &udpopt) < 0)
		fatal("setting UDP options failed");

	if ((irdp_fd= open(ip_device, O_RDWR)) < 0) fatal(ip_device);

	ipopt.nwio_flags= NWIO_COPY | NWIO_EN_LOC | NWIO_EN_BROAD
			| NWIO_REMANY | NWIO_PROTOSPEC
			| NWIO_HDR_O_SPEC | NWIO_RWDATALL;
	ipopt.nwio_tos= 0;
	ipopt.nwio_ttl= 1;
	ipopt.nwio_df= 0;
	ipopt.nwio_hdropt.iho_opt_siz= 0;
	ipopt.nwio_rem= htonl(0xFFFFFFFFL);
	ipopt.nwio_proto= IPPROTO_ICMP;

	if (ioctl(irdp_fd, NWIOSIPOPT, &ipopt) < 0)
		fatal("can't configure ICMP channel");

	asyn_init(&asyn);

	while (1) {
		ssize_t r;

		if (do_rip) {
			/* Try a RIP read. */
			r= asyn_read(&asyn, rip_fd, rip_buf, sizeof(rip_buf));
			if (r < 0) {
				if (errno == EIO) fatal(udp_device);
				if (errno != EINPROGRESS) report(udp_device);
			} else {
				now= time(nil);
				rip_incoming(r);
			}
		}

		if (do_rdisc) {
			/* Try an IRDP read. */
			r= asyn_read(&asyn, irdp_fd, irdp_buf,
							sizeof(irdp_buf));
			if (r < 0) {
				if (errno == EIO) fatal(ip_device);
				if (errno != EINPROGRESS) report(ip_device);
			} else {
				now= time(nil);
				irdp_incoming(r);
			}
		}
		fflush(stdout);

		/* Compute the next wakeup call. */
		timeout= next_sol < next_advert ? next_sol : next_advert;

		/* Wait for a RIP or IRDP packet or a timeout. */
		tv.tv_sec= timeout;
		tv.tv_usec= 0;
		if (asyn_wait(&asyn, 0, timeout == NEVER ? nil : &tv) < 0) {
			/* Timeout? */
			if (errno != EINTR && errno != EAGAIN)
				fatal("asyn_wait()");
			now= time(nil);
			time_functions();
		}
	}
}
Exemplo n.º 29
0
static int setup_listener(char *name, char *port, char *interface, int queue, int ttl, int tos, int reuse, int keepalive)
{
  int fd;
  struct sockaddr_in addr;
  int addrlen;
  int prt;
  struct hostent *hst;
  struct servent *srv;

  addr.sin_family = AF_INET;

  if (port == NULL) {
    fatal_failure(LINET_USAGE, 0, "require a port to bind (-p port)");
  }
  prt = atoi(port);
  if (prt == 0) {
    srv = getservbyname(port, LINET_TCP);
    if (srv == NULL) {
      fatal_failure(LINET_USAGE, 0, "could not convert %s to a nonzero number", port);
    }
    addr.sin_port = srv->s_port;
  } else {
    addr.sin_port = htons(prt);
  }

  if (interface) {
    if (inet_aton(interface, &(addr.sin_addr)) == 0) {
      hst = gethostbyname(interface);
      if (hst == NULL) {
	fatal_failure(LINET_USAGE, 0, "could not convert %s to an address", interface);
      }
      if (hst->h_addrtype != AF_INET) {
	fatal_failure(LINET_USAGE, 0, "%s does not resolve to an ip4 address", interface);
      }
      addr.sin_addr = *(struct in_addr *) hst->h_addr;
    }
  } else {
    addr.sin_addr.s_addr = htonl(INADDR_ANY);
  }

  fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
  if (fd < 0) {
    fatal_failure(LINET_SYSTEM, errno, "could not create an internet socket");
  }

  if(reuse){
    setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (void *)&reuse, sizeof(int));
  }

  if(keepalive){
    setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, (void *)&keepalive, sizeof(int));
  }

  addrlen = sizeof(addr);
  if (bind(fd, (struct sockaddr *) &addr, addrlen) == (-1)) {
    fatal_failure(LINET_SYSTEM, errno, "could not bind an internet socket");
  }

  if (listen(fd, queue) == (-1)) {
    fatal_failure(LINET_SYSTEM, errno, "could not listen on socket");
  }

  if(ttl) {
    if (setsockopt(fd, SOL_IP, IP_TTL, (void *)&ttl, sizeof(int))) {
      fatal_failure(LINET_SYSTEM, errno, "could not set time to live to %d hops", ttl);
    }
  }

  if(tos) {
    if (setsockopt(fd, SOL_IP, IP_TOS, (void *)&tos, sizeof(int))) {
      fatal_failure(LINET_SYSTEM, errno, "could not set type of service to 0x%02x", tos);
    }
  }

  return fd;
}
Exemplo n.º 30
0
TCPSTREAM *tcp_open (char *host,char *service,unsigned long port)
{
  TCPSTREAM *stream = NIL;
  int sock;
  char *s;
  struct sockaddr_in sin;
  struct hostent *host_name;
  char hostname[MAILTMPLEN];
  char tmp[MAILTMPLEN];
  struct protoent *pt = getprotobyname ("tcp");
  struct servent *sv = NIL;
  port &= 0xffff;		/* erase flags */
  if (service) {		/* service specified? */
    if (*service == '*') {	/* yes, special alt driver kludge? */
      sv = getservbyname (service + 1,"tcp");
    }
    else sv = getservbyname (service,"tcp");
  }
				/* user service name port */
  if (sv) port = ntohs (sin.sin_port = sv->s_port);
 				/* copy port number in network format */
  else sin.sin_port = htons (port);
  /* The domain literal form is used (rather than simply the dotted decimal
     as with other Unix programs) because it has to be a valid "host name"
     in mailsystem terminology. */
				/* look like domain literal? */
  if (host[0] == '[' && host[(strlen (host))-1] == ']') {
    strcpy (hostname,host+1);	/* yes, copy number part */
    hostname[(strlen (hostname))-1] = '\0';
    if ((sin.sin_addr.s_addr = inet_addr (hostname)) != -1) {
      sin.sin_family = AF_INET;	/* family is always Internet */
      strcpy (hostname,host);	/* hostname is user's argument */
    }
    else {
      sprintf (tmp,"Bad format domain-literal: %.80s",host);
      mm_log (tmp,ERROR);
      return NIL;
    }
  }

  else {			/* lookup host name, note that brain-dead Unix
				   requires lowercase! */
    strcpy (hostname,host);	/* in case host is in write-protected memory */
    if ((host_name = gethostbyname (lcase (hostname)))) {
				/* copy address type */
      sin.sin_family = host_name->h_addrtype;
				/* copy host name */
      strcpy (hostname,host_name->h_name);
				/* copy host addresses */
      memcpy (&sin.sin_addr,host_name->h_addr,host_name->h_length);
    }
    else {
      sprintf (tmp,"No such host as %.80s",host);
      mm_log (tmp,ERROR);
      return NIL;
    }
  }
				/* get a TCP stream */
  if ((sock = socket (sin.sin_family,SOCK_STREAM,pt ? pt->p_proto : 0)) < 0) {
    sprintf (tmp,"Unable to create TCP socket: %s",strerror (errno));
    mm_log (tmp,ERROR);
    return NIL;
  }
#if 0
  /* Maybe this test is necessary.  It depends upon how VMS implements
   * fd_set.  UNIX-style fd_set needs it; Windows-style does not.
   */
  else if (sock >= FD_SETSIZE) {/* unselectable sockets are useless */
    sprintf (tmp,"Unable to create selectable TCP socket (%d >= %d)",
	     sock,FD_SETSIZE);
    close (sock);
    return NIL;
  }
#endif
				/* open connection */
  if (connect (sock,(struct sockaddr *)&sin,sizeof (sin)) < 0) {
    sprintf (tmp,"Can't connect to %.80s,%d: %s",hostname,port,
	     strerror (errno));
    mm_log (tmp,ERROR);
    return NIL;
  }
				/* create TCP/IP stream */
  stream = (TCPSTREAM *) fs_get (sizeof (TCPSTREAM));
				/* copy official host name */
  stream->host = cpystr (hostname);
				/* get local name */
  gethostname (tmp,MAILTMPLEN-1);
  stream->localhost = cpystr ((host_name = gethostbyname (tmp)) ?
			      host_name->h_name : tmp);
				/* init sockets */
  stream->port = port;		/* port number */
  stream->tcpsi = stream->tcpso = sock;
  stream->ictr = 0;		/* init input counter */
  return stream;		/* return success */
}