Exemplo n.º 1
0
int xioparsenetwork_ip4(const char *rangename, struct xiorange *range) {
   struct hostent *maskaddr;
   struct in_addr *netaddr_in = &range->netaddr.ip4.sin_addr;
   struct in_addr *netmask_in = &range->netmask.ip4.sin_addr;
   char *rangename1;	/* a copy of rangename with writing allowed */
   char *delimpos;	/* absolute address of delimiter */
   unsigned int bits;	/* netmask bits */

   if ((rangename1 = strdup(rangename)) == NULL) {
      Error1("strdup(\"%s\"): out of memory", rangename);
      return STAT_RETRYLATER;
   }

   if (delimpos = strchr(rangename1, '/')) {
      char *endptr;
      bits = strtoul(delimpos+1, &endptr, 10);
      if (! ((*(delimpos+1) != '\0') && (*endptr == '\0'))) {
	 Error1("not a valid netmask in \"%s\"", rangename);
	 bits = 32;	/* most secure selection */
      } else if (bits > 32) {
	 Error1("netmask \"%s\" is too large", rangename);
	 bits = 32;
      }
      if (bits <= 0) {
	 netmask_in->s_addr = 0;
      } else {
	 netmask_in->s_addr = htonl((0xffffffff << (32-bits)));
      }
   } else if (delimpos = strchr(rangename1, ':')) {
      if ((maskaddr = Gethostbyname(delimpos+1)) == NULL) {
	 /* note: cast is req on AIX: */
	 Error2("gethostbyname(\"%s\"): %s", delimpos+1,
		h_errno == NETDB_INTERNAL ? strerror(errno) :
		(char *)hstrerror(h_errno));
	 return STAT_NORETRY;
      }
      netmask_in->s_addr = *(uint32_t *)maskaddr->h_addr_list[0];
   } else {
      Error1("xioparsenetwork_ip4(\"%s\",,): missing netmask delimiter", rangename);
      free(rangename1);
      return STAT_NORETRY;
   }
   {
      struct hostent *nameaddr;
      *delimpos = 0;
      if ((nameaddr = Gethostbyname(rangename1)) == NULL) {
	 /* note: cast is req on AIX: */
	 Error2("gethostbyname(\"%s\"): %s", rangename1,
		h_errno == NETDB_INTERNAL ? strerror(errno) :
		(char *)hstrerror(h_errno));
	    free(rangename1);
	 return STAT_NORETRY;
      }
      netaddr_in->s_addr = *(uint32_t *)nameaddr->h_addr_list[0];
   }
   free(rangename1);
   return STAT_OK;
}
Exemplo n.º 2
0
// call(2, localhost)
int retrievesAndPrintsDNSHostEntry(int argc, char** argv) {
    char** pp;
    struct in_addr addr;
    struct hostent *hostp;

    if (argc != 2) {
        fprintf(stderr, "usage: %s <domain name or dotted-decimal>\n", argv[0]);
        exit(0);
    }

    if (inet_aton(argv[1], &addr) != 0) {
        hostp = Gethostbyaddr((const char*)&addr, sizeof(addr), AF_INET);
    } else {
        hostp = Gethostbyname(argv[1]);
    }

    printf("official hostname: %s\n", hostp->h_name);

    for (pp = hostp->h_aliases; *pp != NULL; pp++) {
        printf("alias: %s\n", *pp);
    }

    for (pp = hostp->h_addr_list; *pp != NULL; pp++) {
        addr.s_addr = ((struct in_addr *) *pp)->s_addr;
        printf("address: %s\n", inet_ntoa(addr));
    }
}
Exemplo n.º 3
0
Arquivo: in_addr.c Projeto: kkaneda/vm
in_addr_t 
InAddr_resolve ( const char *name )
{
	ASSERT ( name != NULL );

	{
		struct in_addr x;
		int retval = inet_pton ( AF_INET, name, &x );
		if  ( retval > 0 )
			return x.s_addr;
	}

	{
		struct hostent hp;    
		bool_t success;
		in_addr_t retval;

		success = Gethostbyname ( name, &hp );
		if  ( ! success )
			return INADDR_NONE;

		Mmove ( &retval, *hp.h_addr_list, sizeof ( in_addr_t ) );
		return retval;
	}
}
Exemplo n.º 4
0
int main(int argc, char *argv[]) {
	char **pp; /* cursor */
	struct in_addr addr; /* holds the IP in integer form */
	struct hostent *hostp; /* holds various info about the server */

	if (argc != 2) {
		fprintf(stderr, "usage: %s <domain name or dotted-decimal>\n", argv[0]);
		return 0;
	}

	/*inet_aton will convert a dotted decimal into an in_addr. If the user has
	  given a named form, this will be 0, and we'll use Gethostbyname. */
	if (inet_aton(argv[1], &addr) != 0)
		hostp = Gethostbyaddr((const char*) &addr, sizeof(addr), AF_INET);
	else
		hostp = Gethostbyname(argv[1]);

	printf("Official hostname: %s\n", hostp->h_name);

	for (pp=hostp->h_aliases; *pp != NULL; ++pp)
		printf("alias: %s\n", *pp);

	for (pp = hostp->h_addr_list; *pp != NULL; ++pp) {
		addr.s_addr = ((struct in_addr*)*pp)->s_addr;
		printf("address: %s\n", inet_ntoa(addr));
	}

	return 0;
}
Exemplo n.º 5
0
int
main(int argc, char **argv)
{
	char			*ptr, **pptr;
	char			str[INET_ADDRSTRLEN];
	struct hostent	*hptr;

	while (--argc > 0) {
		ptr = *++argv;
		try {
			hptr = Gethostbyname(ptr);
		} catch (const std::exception &e) {
			std::cout << e.what() << std::endl;
			continue;
		}
		printf("official hostname: %s\n", hptr->h_name);

		for (pptr = hptr->h_aliases; *pptr != NULL; pptr++)
			printf("\talias: %s\n", *pptr);

		switch (hptr->h_addrtype) {
		case AF_INET:
			pptr = hptr->h_addr_list;
			for ( ; *pptr != NULL; pptr++)
				printf("\taddress: %s\n",
					inet_ntop(hptr->h_addrtype, *pptr, str, sizeof(str)));
			break;

		default:
			perror("unknown address type");
			break;
		}
	}
	exit(0);
}
Exemplo n.º 6
0
int main(int argc, char **argv)
{
    char **pp;
    struct in_addr addr;
    struct hostent *hostp;

    if (argc != 2) {
        fprintf(stderr, "usage: %s <domain name or dotted-decimal>\n", argv[0]);
        exit(0);
    }

    if (inet_aton(argv[1], &addr) != 0)
        hostp = Gethostbyaddr((const char *)&addr, sizeof(addr), AF_INET);  //AF_INET等于0,指的是使用IPV4
    else
        hostp = Gethostbyname(argv[1]);

    printf("official hostname: %s\n", hostp->h_name);

    for (pp = hostp->h_aliases; *pp != NULL; pp++) {  //aliase->别名
        printf("alias: %s\n", *pp);
    }

    for (pp = hostp->h_addr_list; *pp != NULL; pp++) {
        //printf("%s\n", *pp);
        addr.s_addr = ((struct in_addr *)*pp)->s_addr;   //*pp 是 char *类型
        /* expected ‘struct in_addr’ but argument is of type ‘struct in_addr *’ */
        printf("address: %s\n", inet_ntoa(addr));
    }
    exit(0);
}
Exemplo n.º 7
0
int xioparsenetwork_ip4(const char *rangename, struct xiorange *range) {
   struct hostent *maskaddr;
   struct in_addr *netaddr_in = &range->netaddr.ip4.sin_addr;
   struct in_addr *netmask_in = &range->netmask.ip4.sin_addr;
   char *rangename1;	/* a copy of rangename with writing allowed */
   char *delimpos;	/* absolute address of delimiter */
   int bits;

   if ((rangename1 = strdup(rangename)) == NULL) {
      Error1("strdup(\"%s\"): out of memory", rangename);
      return STAT_RETRYLATER;
   }

   if (delimpos = strchr(rangename1, '/')) {
      bits = strtoul(delimpos+1, NULL, 10);
      netmask_in->s_addr = htonl((0xffffffff << (32-bits)));
   } else if (delimpos = strchr(rangename1, ':')) {
      if ((maskaddr = Gethostbyname(delimpos+1)) == NULL) {
	 /* note: cast is req on AIX: */
	 Error2("gethostbyname(\"%s\"): %s", delimpos+1,
		h_errno == NETDB_INTERNAL ? strerror(errno) :
		(char *)hstrerror(h_errno));
	 return STAT_NORETRY;
      }
      netmask_in->s_addr = *(uint32_t *)maskaddr->h_addr_list[0];
   } else {
      Error1("xioparsenetwork_ip4(\"%s\",,): missing netmask delimiter", rangename);
      free(rangename1);
      return STAT_NORETRY;
   }
   {
      struct hostent *nameaddr;
      *delimpos = 0;
      if ((nameaddr = Gethostbyname(rangename1)) == NULL) {
	 /* note: cast is req on AIX: */
	 Error2("gethostbyname(\"%s\"): %s", rangename1,
		h_errno == NETDB_INTERNAL ? strerror(errno) :
		(char *)hstrerror(h_errno));
	    free(rangename1);
	 return STAT_NORETRY;
      }
      netaddr_in->s_addr = *(unsigned long *)nameaddr->h_addr_list[0];
   }
   free(rangename1);
   return STAT_OK;
}
Exemplo n.º 8
0
int
reverse(thread_pool_t *info, thread_ctx_t *thread_ctx, edict_t *edict)
{
	chkresult_t *result;
	struct hostent *canonicalhost, *reversehost;

	grey_tuple_t *request;
	const char *client_address;
        char buf[INET_ADDRSTRLEN];
	const char *ptr;
	mseconds_t timelimit;

	request = (grey_tuple_t *)edict->job;
	client_address = request->client_address;
	assert(client_address);

	result = (chkresult_t *)Malloc(sizeof(chkresult_t));
	memset(result, 0, sizeof(*result));
	result->judgment = J_UNDEFINED;
	result->checkname = "reverse";

	timelimit = edict->timelimit;

	reversehost = Gethostbyaddr_str(client_address, timelimit);
	if (reversehost) {
                logstr(GLOG_INSANE, "client_address (%s) has a PTR record (%s)",
                        client_address, reversehost->h_name);
		canonicalhost = Gethostbyname(reversehost->h_name, timelimit);
		if (canonicalhost) {
			ptr = inet_ntop(AF_INET, canonicalhost->h_addr_list[0], buf, INET_ADDRSTRLEN);
			assert(ptr);
			logstr(GLOG_INSANE, "client_ip (%s) canonical (%s)",
				client_address, buf);
			if (strcmp(buf, client_address)) {
				logstr(GLOG_DEBUG, "client_address (%s) not canonical (%s)",
					client_address, buf);
				result->judgment = J_SUSPICIOUS;
				result->weight = 1; /* FIXME */
			}
		} else {
			logstr(GLOG_DEBUG, "No A for PTR for client_ip (%s)", client_address);
			result->judgment = J_SUSPICIOUS;
			result->weight = 1;
		}
	} else {
		logstr(GLOG_DEBUG, "client_ip (%s) has no PTR record", client_address);
		result->judgment = J_SUSPICIOUS;
		result->weight = 1;
	}

	send_result(edict, result);
	logstr(GLOG_DEBUG, "reverse returning");
	request_unlink(request);

	return 0;
}
Exemplo n.º 9
0
 struct hostent *Gethostbyname(const char *name) {
    struct hostent *hp;
    if((hp = gethostbyname(name)) == NULL) {
       switch(h_errno) {
         case TRY_AGAIN:      fprintf(stdout," Warning: Gethostbyname returned TRY_AGAIN.\n");
                              fflush(stdout);  return Gethostbyname(name); break;
         case NO_DATA:        fprintf(stdout," Error: Gethostbyname(%s) returned NO_DATA.\n",name); break;
         case NO_RECOVERY:    fprintf(stdout," Error: Gethostbyname(%s) returned NO_RECOVERY.\n",name); break;
         case HOST_NOT_FOUND: fprintf(stdout," Error: Gethostbyname(%s) returned HOST_NOT_FOUND.\n",name); break;
         default:             fprintf(stdout," Error: Gethostbyname(%s) returned an unknown error (%s).\n",name,DDI_Id()); break;
       } 
       Fatal_error(911);
    }
    return hp;
 }
Exemplo n.º 10
0
int main(int argc, char **argv) {
    int listenfd, connfd;
    socklen_t clientlen = sizeof(struct sockaddr_in);
    struct sockaddr_in clientaddr;
    user* u;

    /* Init node and set port accoriding to configue file */
    init_node(argc, argv);

    /* Init the linked list of channel and the table of user */
    init_channel();
    init_user();
    
    /* Init server socket and set it as unblocked */
    listenfd = init_unblocking_server_socket(curr_node_config_entry->irc_port);

    /* connect to local daemon */
    local_client_fd = socket_connect(curr_node_config_entry->ipaddr,curr_node_config_entry->local_port);

    /* Init struct pool */
    init_pool();

    add_listen_fd(listenfd);

    while (1) {
        /* Wait for listening/connected descriptor(s) to become ready */
        p.ready_set = p.read_set;
        p.nready = Select(p.maxfd+1, &p.ready_set, NULL, NULL, NULL);

        /* If listening descriptor ready, add new client to pool */
        if (FD_ISSET(listenfd, &p.ready_set)) {
            connfd = Accept(listenfd, (SA *)&clientaddr, &clientlen);

            /* create a user struct for the connect fd */
            u = (user*) Calloc(1,sizeof(user));
            user_table[connfd] = u;

            /*set server_name and host_name for user */
            u->host_name = strdup(Gethostbyaddr((const char*)&clientaddr.sin_addr,sizeof(clientaddr.sin_addr),AF_INET)->h_name);
            u->server_name = strdup(Gethostbyname("localhost")->h_name);

            add_client(connfd);
        }

        /* Echo a text line from each ready connected descriptor */
        check_clients();
    }
}
Exemplo n.º 11
0
int _xioopen_proxy_prepare(struct proxyvars *proxyvars, struct opt *opts,
			   const char *targetname, const char *targetport) {
   struct hostent *host;

   retropt_bool(opts, OPT_IGNORECR, &proxyvars->ignorecr);
   retropt_bool(opts, OPT_PROXY_RESOLVE, &proxyvars->doresolve);
   retropt_string(opts, OPT_PROXY_AUTHORIZATION, &proxyvars->authstring);

   if (proxyvars->doresolve) {
      /* currently we only resolve to IPv4 addresses. This is in accordance to
	 RFC 2396; however once it becomes clear how IPv6 addresses should be
	 represented in CONNECT commands this code might be extended */
      host = Gethostbyname(targetname);
      if (host == NULL) {
	 int level = E_WARN;
	 /* note: cast is req on AIX: */
	 Msg2(level, "gethostbyname(\"%s\"): %s", targetname,
	      h_errno == NETDB_INTERNAL ? strerror(errno) :
	      (char *)hstrerror(h_errno)/*0 h_messages[h_errno-1]*/);

	 proxyvars->targetaddr = strdup(targetname);
      } else {
#define LEN 16	/* www.xxx.yyy.zzz\0 */
	 if ((proxyvars->targetaddr = Malloc(LEN)) == NULL) {
	    return STAT_RETRYLATER;
	 }
	 snprintf(proxyvars->targetaddr, LEN, "%u.%u.%u.%u",
		  (unsigned char)host->h_addr_list[0][0],
		  (unsigned char)host->h_addr_list[0][1],
		  (unsigned char)host->h_addr_list[0][2],
		  (unsigned char)host->h_addr_list[0][3]);
#undef LEN
      }
   } else {
      proxyvars->targetaddr = strdup(targetname);
   }

   proxyvars->targetport = htons(parseport(targetport, IPPROTO_TCP));

   return STAT_OK;
}
Exemplo n.º 12
0
/* $begin open_clientfd */
int open_clientfd(char* hostname, int port)
{
	int clientfd;
	struct hostent* hp;
	struct sockaddr_in serveraddr;
	if((clientfd = socket(AF_INET,SOCK_STREAM,0)) < 0)
		return -1;/*Check errno for cause of error*/

	/* Fill in the server's IP address and port*/
	if((hp = Gethostbyname(hostname)) == NULL)
		return -2;
	bzero((char*)&serveraddr,sizeof(serveraddr));
	serveraddr.sin_family = AF_INET;
	bcopy((char*)hp->h_addr_list[0],(char*)&serveraddr.sin_addr.s_addr,hp->h_length);
	serveraddr.sin_port = htons(port);

	/* Establish a connection with the server*/
	if(connect(clientfd,(SA*)&serveraddr,sizeof(serveraddr)) < 0)
		return -1;
	return clientfd;
}
Exemplo n.º 13
0
/* the ultimate(?) socat resolver function
 node: the address to be resolved; supported forms:
   1.2.3.4 (IPv4 address)
   [::2]   (IPv6 address)
   hostname (hostname resolving to IPv4 or IPv6 address)
   hostname.domain (fq hostname resolving to IPv4 or IPv6 address)
 service: the port specification; may be numeric or symbolic
 family: PF_INET, PF_INET6, or PF_UNSPEC permitting both
 socktype: SOCK_STREAM, SOCK_DGRAM
 protocol: IPPROTO_UDP, IPPROTO_TCP
 sau: an uninitialized storage for the resulting socket address
 returns: STAT_OK, STAT_RETRYLATER
*/
int xiogetaddrinfo(const char *node, const char *service,
		   int family, int socktype, int protocol,
		   union sockaddr_union *sau, socklen_t *socklen,
		   unsigned long res_opts0, unsigned long res_opts1) {
   int port = -1;	/* port number in network byte order */
   char *numnode = NULL;
   size_t nodelen;
   unsigned long save_res_opts = 0;
#if HAVE_GETADDRINFO
   struct addrinfo hints = {0};
   struct addrinfo *res = NULL;
#else /* HAVE_GETIPNODEBYNAME || nothing */
   struct hostent *host;
#endif
   int error_num;

#if HAVE_RESOLV_H
   if (res_opts0 | res_opts1) {
      if (!(_res.options & RES_INIT)) {
         Res_init();	/*!!! returns -1 on error */
      }
      save_res_opts = _res.options;
      _res.options &= ~res_opts0;
      _res.options |= res_opts1;
      Debug2("changed _res.options from 0x%lx to 0x%lx",
	     save_res_opts, _res.options);
   }
#endif /* HAVE_RESOLV_H */
   memset(sau, 0, *socklen);
   sau->soa.sa_family = family;

   /* if service is numeric we don't want to have a lookup (might take long
      with NIS), so we handle this specially */
   if (service && isdigit(service[0]&0xff)) {
      char *extra;
      port = htons(strtoul(service, &extra, 0));
      if (*extra != '\0') {
	 Warn2("xiogetaddrinfo(, \"%s\", ...): extra trailing data \"%s\"",
	       service, extra);
      }
      service = NULL; 
   }

   /* the resolver functions might handle numeric forms of node names by
      reverse lookup, that's not what we want.
      So we detect these and handle them specially */
   if (node && isdigit(node[0]&0xff)) {
#if HAVE_GETADDRINFO
      hints.ai_flags |= AI_NUMERICHOST;
#endif /* HAVE_GETADDRINFO */
      if (family == PF_UNSPEC) {
	 family = PF_INET;
#if HAVE_GETADDRINFO
      } else if (family == PF_INET6) {
	 /* map "explicitely" into IPv6 address space; getipnodebyname() does
	    this with AI_V4MAPPED, but not getaddrinfo() */
	 if ((numnode = Malloc(strlen(node)+7+1)) == NULL) {
#if HAVE_RESOLV_H
	    if (res_opts0 | res_opts1) {
	       _res.options = (_res.options & (~res_opts0&~res_opts1) |
			       save_res_opts& ( res_opts0| res_opts1));
	    }
#endif
	    return STAT_NORETRY;
	 }
	 sprintf(numnode, "::ffff:%s", node);
	 node = numnode;
	 hints.ai_flags |= AI_NUMERICHOST;
#endif /* HAVE_GETADDRINFO */
      }
#if WITH_IP6
   } else if (node && node[0] == '[' && node[(nodelen=strlen(node))-1]==']') {
      if ((numnode = Malloc(nodelen-1)) == NULL) {
#if HAVE_RESOLV_H
	 if (res_opts0 | res_opts1) {
	    _res.options = (_res.options & (~res_opts0&~res_opts1) |
			    save_res_opts& ( res_opts0| res_opts1));
	 }
#endif
	 return STAT_NORETRY;
      }
      strncpy(numnode, node+1, nodelen-2);
      numnode[nodelen-2] = '\0';
      node = numnode;
#if HAVE_GETADDRINFO
      hints.ai_flags |= AI_NUMERICHOST;
#endif /* HAVE_GETADDRINFO */
      if (family == PF_UNSPEC)  family = PF_INET6;
#endif /* WITH_IP6 */
   }

#if HAVE_GETADDRINFO
   if (node != NULL || service != NULL) {
      struct addrinfo *record;

      if (socktype != SOCK_STREAM && socktype != SOCK_DGRAM) {
	 /* actual socket type value is not supported - fallback to a good one */
	 socktype = SOCK_DGRAM;
      }
      if (protocol != IPPROTO_TCP && protocol != IPPROTO_UDP) {
	 /* actual protocol value is not supported - fallback to a good one */
	 if (socktype == SOCK_DGRAM) {
	    protocol = IPPROTO_UDP;
	 } else {
	    protocol = IPPROTO_TCP;
	 }
      }
      hints.ai_flags |= AI_PASSIVE;
      hints.ai_family = family;
      hints.ai_socktype = socktype;
      hints.ai_protocol = protocol;
      hints.ai_addrlen = 0;
      hints.ai_addr = NULL;
      hints.ai_canonname = NULL;
      hints.ai_next = NULL;

      if ((error_num = Getaddrinfo(node, service, &hints, &res)) != 0) {
	 Error7("getaddrinfo(\"%s\", \"%s\", {%d,%d,%d,%d}, {}): %s",
		node, service, hints.ai_flags, hints.ai_family,
		hints.ai_socktype, hints.ai_protocol,
		(error_num == EAI_SYSTEM)?
		strerror(errno):gai_strerror(error_num));
	 if (res != NULL)  freeaddrinfo(res);
	 if (numnode)  free(numnode);

#if HAVE_RESOLV_H
	 if (res_opts0 | res_opts1) {
	    _res.options = (_res.options & (~res_opts0&~res_opts1) |
			    save_res_opts& ( res_opts0| res_opts1));
	 }
#endif
	 return STAT_RETRYLATER;
      }
      service = NULL;	/* do not resolve later again */

      record = res;
      if (family == PF_UNSPEC && xioopts.preferred_ip == '0') {
	 /* we just take the first result */
	 family = res[0].ai_addr->sa_family;
      }
      if (family == PF_UNSPEC) {
	 int trypf;
	 trypf = (xioopts.preferred_ip=='6'?PF_INET6:PF_INET);
	 /* we must look for a matching entry */
	 while (record != NULL) {
	    if (record->ai_family == trypf) {
	       family = trypf;
	       break;	/* family and record set accordingly */
	    }
	    record = record->ai_next;
	 }
	 if (record == NULL) {
	    /* we did not find a "preferred" entry, take the first */
	    record = res;
	    family = res[0].ai_addr->sa_family;
	 }
      }

      switch (family) {
#if WITH_IP4
      case PF_INET:
	 if (*socklen > record->ai_addrlen) {
	    *socklen = record->ai_addrlen;
	 }
	 memcpy(&sau->ip4, record->ai_addr, *socklen);
	 break;
#endif /* WITH_IP4 */
#if WITH_IP6
      case PF_INET6:
#if _AIX
	 /* older AIX versions pass wrong length, so we correct it */
	 record->ai_addr->sa_len = sizeof(struct sockaddr_in6);
#endif
	 if (*socklen > record->ai_addrlen) {
	    *socklen = record->ai_addrlen;
	 }
	 memcpy(&sau->ip6, record->ai_addr, *socklen);
	 break;
#endif /* WITH_IP6 */
      default:
	 Error1("address resolved to unknown protocol family %d",
		record->ai_addr->sa_family);
	 break;
      }
      freeaddrinfo(res);
   } else {
      switch (family) {
#if WITH_IP4
      case PF_INET:  *socklen = sizeof(sau->ip4); break;
#endif /* WITH_IP4 */
#if WITH_IP6
      case PF_INET6: *socklen = sizeof(sau->ip6); break;
#endif /* WITH_IP6 */
      }
   }

#elif HAVE_GETIPNODEBYNAME /* !HAVE_GETADDRINFO */

   if (node != NULL) {
      /* first fallback is getipnodebyname() */
      if (family == PF_UNSPEC) {
#if WITH_IP4 && WITH_IP6
	 family = xioopts.default_ip=='6'?PF_INET6:PF_INET;
#elif WITH_IP6
	 family = PF_INET6;
#else
	 family = PF_INET;
#endif
      }
      host = Getipnodebyname(node, family, AI_V4MAPPED, &error_num);
      if (host == NULL) {
	 const static char ai_host_not_found[] = "Host not found";
	 const static char ai_no_address[]     = "No address";
	 const static char ai_no_recovery[]    = "No recovery";
	 const static char ai_try_again[]      = "Try again";
	 const char *error_msg = "Unknown error";
	 switch (error_num) {
	 case HOST_NOT_FOUND: error_msg = ai_host_not_found; break;
	 case NO_ADDRESS:     error_msg = ai_no_address;
	 case NO_RECOVERY:    error_msg = ai_no_recovery;
	 case TRY_AGAIN:      error_msg = ai_try_again;
	 }
	 Error2("getipnodebyname(\"%s\", ...): %s", node, error_msg);
      } else {
	 switch (family) {
#if WITH_IP4
	 case PF_INET:
	    *socklen = sizeof(sau->ip4);
	    sau->soa.sa_family = PF_INET;
	    memcpy(&sau->ip4.sin_addr, host->h_addr_list[0], 4);
	    break;
#endif
#if WITH_IP6
	 case PF_INET6:
	    *socklen = sizeof(sau->ip6);
	    sau->soa.sa_family = PF_INET6;
	    memcpy(&sau->ip6.sin6_addr, host->h_addr_list[0], 16);
	    break;
#endif
	 }
      }
      freehostent(host);
   }

#else /* !HAVE_GETIPNODEBYNAME */

   if (node != NULL) {
      /* this is not a typical IP6 resolver function - but Linux
	 "man gethostbyname" says that the only supported address type with
	 this function is AF_INET _at present_, so maybe this fallback will
	 be useful somewhere sometimesin a future even for IP6 */
      if (family == PF_UNSPEC) {
#if WITH_IP4 && WITH_IP6
	 family = xioopts.default_ip=='6'?PF_INET6:PF_INET;
#elif WITH_IP6
	 family = PF_INET6;
#else
	 family = PF_INET;
#endif
      }
      /*!!! try gethostbyname2 for IP6 */
      if ((host = Gethostbyname(node)) == NULL) {
	 Error2("gethostbyname(\"%s\"): %s", node,
		h_errno == NETDB_INTERNAL ? strerror(errno) :
		hstrerror(h_errno));
#if HAVE_RESOLV_H
	 if (res_opts0 | res_opts1) {
	    _res.options = (_res.options & (~res_opts0&~res_opts1) |
			    save_res_opts& ( res_opts0| res_opts1));
	 }
#endif
	 return STAT_RETRYLATER;
      }
      if (host->h_addrtype != family) {
	 Error2("xioaddrinfo(): \"%s\" does not resolve to %s",
		node, family==PF_INET?"IP4":"IP6");
      } else {
	 switch (family) {
#if WITH_IP4
	 case PF_INET:
	    *socklen = sizeof(sau->ip4);
	    sau->soa.sa_family = PF_INET;
	    memcpy(&sau->ip4.sin_addr, host->h_addr_list[0], 4);
	    break;
#endif /* WITH_IP4 */
#if WITH_IP6
	 case PF_INET6:
	    *socklen = sizeof(sau->ip6);
	    sau->soa.sa_family = PF_INET6;
	    memcpy(&sau->ip6.sin6_addr, host->h_addr_list[0], 16);
	    break;
#endif /* WITH_IP6 */
	 }
      }
   }

#endif

#if WITH_TCP || WITH_UDP
   if (service) {
      port = parseport(service, protocol);
   }
   if (port >= 0) {
      switch (family) {
#if WITH_IP4
      case PF_INET:  sau->ip4.sin_port  = port; break;
#endif /* WITH_IP4 */
#if WITH_IP6
      case PF_INET6: sau->ip6.sin6_port = port; break;
#endif /* WITH_IP6 */
      }
   }      
#endif /* WITH_TCP || WITH_UDP */

   if (numnode)  free(numnode);

#if HAVE_RESOLV_H
   if (res_opts0 | res_opts1) {
      _res.options = (_res.options & (~res_opts0&~res_opts1) |
		      save_res_opts& ( res_opts0| res_opts1));
   }
#endif /* HAVE_RESOLV_H */
   return STAT_OK;
}
Exemplo n.º 14
0
int
helo(thread_pool_t *info, thread_ctx_t *thread_ctx, edict_t *edict)
{
    chkresult_t *result;
    struct hostent *host, *reversehost;
    grey_tuple_t *request;
    const char *helostr;
    const char *client_address;
    char addrstrbuf[INET_ADDRSTRLEN];
    const char *ptr;
    mseconds_t timelimit;

    request = (grey_tuple_t *)edict->job;
    helostr = request->helo_name;
    client_address = request->client_address;
    assert(helostr);
    assert(client_address);

    result = (chkresult_t *)Malloc(sizeof(chkresult_t));
    memset(result, 0, sizeof(*result));
    result->judgment = J_UNDEFINED;
    result->checkname = "helo";

    timelimit = edict->timelimit;

    /* check the validity of helo string */
    if (check_helo(helostr)) {
        logstr(GLOG_DEBUG, "Syntactically suspicious helo name");
        /* one for invalid helo string AND one for not matching the client ip */
        result->weight += 2; /* FIXME */
        /* no point in doing dns queries as invalid helo wouldn't match the client ip */
        goto FINISH;
    }

    /* check if helo resolves to client ip */
    host = Gethostbyname(helostr, timelimit);
    if (host) {
        ptr = inet_ntop(AF_INET, host->h_addr_list[0], addrstrbuf, INET_ADDRSTRLEN);
        if (NULL == ptr) {
            /* this should never happen */
            logstr(GLOG_ERROR, "helo_name resolved to an invalid ip");
            goto FINISH;
        }
        logstr(GLOG_INSANE, "client_address (%s), helo (%s)",
               client_address, addrstrbuf); /* FIXME */
        if (strcmp(addrstrbuf, client_address)) {
            logstr(GLOG_DEBUG, "helo name (%s) does not resolve to client address (%s)",
                   helostr, client_address);
            result->weight += 1; /* FIXME */
        }
    } else {
        logstr(GLOG_DEBUG, "helo_name not resolvable");
        result->weight += 1; /* FIXME */
    }

    /* check if client's PTR record match helo */
    reversehost = Gethostbyaddr_str(client_address, timelimit);
    if (reversehost) {
        logstr(GLOG_INSANE, "client_address (%s) has a PTR record (%s)",
               client_address, reversehost->h_name);
        if (strcmp(reversehost->h_name, helostr)) {
            logstr(GLOG_DEBUG, "PTR for client_address (%s) differs from helo_name (%s)",
                   reversehost->h_name, helostr);
            result->weight += 1; /* FIXME */
        }
    } else {
        logstr(GLOG_INSANE, "client_address (%s) does not have a PTR record");
        result->weight += 1; /* FIXME */
    }

FINISH:
    if (result->weight > 0)
        result->judgment = J_SUSPICIOUS;
    send_result(edict, result);
    logstr(GLOG_DEBUG, "helo returning");
    request_unlink(request);

    return 0;
}