bool verip (std::string ip, int af) { /* Linux supports getipnodebyname as well, but since I'm unsure about the other OS's, this directive seems appropriate */ #ifndef SOLARIS h_errno = 0; if (af == 4){ if (gethostbyname2(ip.c_str(), AF_INET) != NULL) return true; else { if(h_errno == HOST_NOT_FOUND) cout << "Could not find IPv4 host " << ip << endl; else if (h_errno == NO_ADDRESS || h_errno == NO_DATA) cout << ip << " is valid, but lacks a corresponding ip address" << endl; else if (h_errno == TRY_AGAIN) cout << "Unable to obtain an answer from a DNS-server" << endl; else cout << "An error occured while verifying " << ip << endl; } } else if(af == 6) { h_errno = 0; if (gethostbyname2(ip.c_str(),AF_INET6) != NULL) return true; else { if(h_errno == HOST_NOT_FOUND) cout << "Could not find IPv4 host " << ip << endl; else if (h_errno == NO_ADDRESS || h_errno == NO_DATA) cout << ip << " is valid, but lacks a corresponding ip address" << endl; else if (h_errno == TRY_AGAIN) cout << "Unable to obtain an answer from a DNS-server" << endl; else cout << "An error occured while verifying " << ip << endl; } } #endif #ifdef SOLARIS int error_num; if (af==4) { if (getipnodebyname(ip.c_str(), AF_INET, 0, &error_num) != NULL) return true; else cout << "This IPv4 address: " << ip << " is wrongly formatted." << endl; } else if (af == 6) { if (getipnodebyname(ip.c_str(), AF_INET6, 0, &error_num) != NULL) return true; else cout << "This IPv6 address: " << ip << " is wrongly formatted." << endl; } #endif return false; }
int main(int argc, char **argv) { struct hostent *he; int error; (void)argc; while (argv[1] != NULL) { he = gethostbyname(argv[1]); print_he(he, h_errno, "gethostbyname", argv[1]); he = getipnodebyname(argv[1], AF_INET6, AI_DEFAULT|AI_ALL, &error); print_he(he, error, "getipnodebyname", argv[1]); if (he != NULL) freehostent(he); he = getipnodebyname(argv[1], AF_INET6, AI_DEFAULT, &error); print_he(he, error, "getipnodebyname", argv[1]); if (he != NULL) freehostent(he); argv++; } return (0); }
/* * smb_gethostbyname * * Looks up a host by the given name. The host entry can come * from any of the sources for hosts specified in the * /etc/nsswitch.conf and the NetBIOS cache. * * XXX Invokes nbt_name_resolve API once the NBTD is integrated * to look in the NetBIOS cache if getipnodebyname fails. * * Caller should invoke freehostent to free the returned hostent. */ struct hostent * smb_gethostbyname(const char *name, int *err_num) { struct hostent *h; h = getipnodebyname(name, AF_INET, 0, err_num); if ((h == NULL) || h->h_length != INADDRSZ) h = getipnodebyname(name, AF_INET6, AI_DEFAULT, err_num); return (h); }
static int match_interfaces(char *host) { struct in6_addr **lif = local_interfaces(); struct hostent *hp; int rc = 0; int errnum; /* are there any local interfaces */ if (lif == NULL) return (0); /* cycle through the host db addresses */ hp = getipnodebyname(host, AF_INET6, AI_ALL|AI_V4MAPPED, &errnum); if (hp != NULL) { struct in6_addr **tmp = (struct in6_addr **)hp->h_addr_list; int i; for (i = 0; ((rc == 0) && (tmp[i] != NULL)); i++) { int j; for (j = 0; ((rc == 0) && (lif[j] != NULL)); j++) if (memcmp(tmp[i], lif[j], sizeof (struct in6_addr)) == 0) rc = 1; } } free(lif); return (rc); }
/* * Given a host name, check to see if it points to the local host. * If it does, return 1, else return 0. * * The strategy is this: translate the host name argument to a list of * addresses. Then compare each of those addresses to the addresses of * network interfaces on this host. */ int is_local_host(char *host) { struct hostent *hp; int err; int flags = AI_DEFAULT; if (hp = getipnodebyname((const char *) host, AF_INET, flags, &err)) if (is_local_if(hp)) return (1); if (hp = getipnodebyname((const char *) host, AF_INET6, flags, &err)) if (is_local_if(hp)) return (1); return (0); }
static void test_getipnodebyname(const char *name, const char *address, int af, int v4map, int all) { struct hostent *hp; unsigned char addrbuf[16]; int len, ret; int error_num; int flags = 0; if (v4map) flags |= AI_V4MAPPED; if (all) flags |= AI_ALL; hp = getipnodebyname(name, af, flags, &error_num); if (hp == NULL) { if (address == NULL && error_num == HOST_NOT_FOUND) return; else if (error_num != HOST_NOT_FOUND) { printf("I:getipnodebyname(%s) failed: %d\n", name, error_num); fails++; return; } else { printf("I:getipnodebyname(%s) returned not found\n", name); fails++; return; } } else { if (af == AF_INET) len = 4; else len = 16; ret = inet_pton(af, address, addrbuf); assert(ret == 1); if (hp->h_addrtype != af) { printf("I:getipnodebyname(%s) returned wrong family\n", name); freehostent(hp); fails++; return; } if (len != (int)hp->h_length || memcmp(hp->h_addr_list[0], addrbuf, hp->h_length) != 0) { char outbuf[16]; (void)inet_ntop(af, hp->h_addr_list[0], outbuf, sizeof(outbuf)); printf("I:getipnodebyname(%s) returned %s, " "expected %s\n", name, outbuf, address); freehostent(hp); fails++; return; } freehostent(hp); } }
static int get_nodes (const char *nodename, const struct addrinfo *hints, int port, int protocol, int socktype, struct addrinfo **res) { struct addrinfo *first = NULL; struct addrinfo **current = &first; int family = PF_UNSPEC; int flags = 0; int ret = EAI_NONAME; int error; if (hints != NULL) { family = hints->ai_family; flags = hints->ai_flags; } #ifdef HAVE_IPV6 if (family == PF_INET6 || family == PF_UNSPEC) { struct hostent *he; he = getipnodebyname (nodename, PF_INET6, 0, &error); if (he != NULL) { ret = add_hostent (port, protocol, socktype, ¤t, const_v6, he, &flags); freehostent (he); } } #endif if (family == PF_INET || family == PF_UNSPEC) { struct hostent *he; he = getipnodebyname (nodename, PF_INET, 0, &error); if (he != NULL) { ret = add_hostent (port, protocol, socktype, ¤t, const_v4, he, &flags); freehostent (he); } } *res = first; return ret; }
struct hostent * gethostbyname_ctx (const char *host, struct ghbnctx *ctx) { assert (ctx != NULL); memset (ctx, 0, sizeof (struct ghbnctx)); ctx->hostent = getipnodebyname (host, AF_UNSPEC, AI_ADDRCONFIG, &ctx->h_err); return ctx->hostent; }
static int print_rh(const char *rh_name) { int herr; struct hostent *hp; in6_addr_t in6; char abuf[INET6_ADDRSTRLEN]; tsol_rhent_t rhent; if ((hp = getipnodebyname(rh_name, AF_INET6, AI_ALL | AI_ADDRCONFIG | AI_V4MAPPED, &herr)) == NULL) { (void) fprintf(stderr, gettext("tninfo: unknown host or " "invalid literal address: %s\n"), rh_name); if (herr == TRY_AGAIN) (void) fprintf(stderr, gettext("\t(try again later)\n")); return (1); } (void) memset(&rhent, 0, sizeof (rhent)); (void) memcpy(&in6, hp->h_addr, hp->h_length); if (IN6_IS_ADDR_V4MAPPED(&in6)) { rhent.rh_address.ta_family = AF_INET; IN6_V4MAPPED_TO_INADDR(&in6, &rhent.rh_address.ta_addr_v4); (void) inet_ntop(AF_INET, &rhent.rh_address.ta_addr_v4, abuf, sizeof (abuf)); } else { rhent.rh_address.ta_family = AF_INET6; rhent.rh_address.ta_addr_v6 = in6; (void) inet_ntop(AF_INET6, &in6, abuf, sizeof (abuf)); } (void) printf(gettext("IP address= %s\n"), abuf); if (tnrh(TNDB_GET, &rhent) != 0) { if (errno == ENOENT) (void) fprintf(stderr, gettext("tninfo: tnrhdb entry " "%1$s does not exist\n"), abuf); else (void) fprintf(stderr, gettext("tninfo: TNDB_GET(%1$s) " "failed: %2$s\n"), abuf, strerror(errno)); return (1); } if (rhent.rh_template[0] != '\0') (void) printf(gettext("Template = %.*s\n"), TNTNAMSIZ, rhent.rh_template); else (void) printf(gettext("No template exists.\n")); return (0); }
static char * pseudo_serialno_from_addr(char *name) { int sd, rc, errnum; char buf[128]; struct hostent *hp; struct xarpreq ar; if (name == NULL) return (NULL); memset(&ar, 0, sizeof (ar)); hp = getipnodebyname(name, AF_INET6, AI_ADDRCONFIG, &errnum); if (hp != NULL) { struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)&ar.xarp_pa; sin6->sin6_family = AF_INET6; (void) memcpy(&sin6->sin6_addr, hp->h_addr_list[0], hp->h_length); } else { struct sockaddr_in *sin = (struct sockaddr_in *)&ar.xarp_pa; sin->sin_family = AF_INET; sin->sin_addr.s_addr = inet_addr(name); } sd = socket(AF_INET, SOCK_DGRAM, 0); ar.xarp_ha.sdl_family = AF_LINK; rc = ioctl(sd, SIOCGXARP, (caddr_t)&ar); close(sd); if (ar.xarp_flags & ATF_COM) { /* use the MAC address */ uchar_t *ea = (uchar_t *)LLADDR(&ar.xarp_ha); addr_to_string("LLADDR-", ea, ar.xarp_ha.sdl_alen, buf, sizeof (buf)); } else if (hp != NULL) { /* use the IPv6 address */ addr_to_string("IPV6ADDR-", (uchar_t *)&hp->h_addr_list[0], hp->h_length, buf, sizeof (buf)); } else { /* use the IPv4 address */ struct sockaddr_in *sin = (struct sockaddr_in *)&ar.xarp_pa; addr_to_string("IPV4ADDR-", (uchar_t *)&sin->sin_addr.s_addr, 4, buf, sizeof (buf)); } return (strdup(buf)); }
/* * Given a host name, check to see if it points to the local host. * If it does, return 1, else return 0. * * The strategy is this: translate the host name argument to a list of * addresses. Then compare each of those addresses to the addresses of * network interfaces on this host. */ int is_local_host(char *host) { #ifdef __sun struct hostent *hp; int err; #ifndef AI_DEFAULT #define AI_DEFAULT (AI_V4MAPPED | AI_ADDRCONFIG) #endif int flags = AI_DEFAULT; if (hp = getipnodebyname((const char *) host, AF_INET, flags, &err)) if (is_local_if(hp)) return (1); if (hp = getipnodebyname((const char *) host, AF_INET6, flags, &err)) if (is_local_if(hp)) return (1); return (0); #else /* !__sun */ return (1); #endif /* !__sun */ }
struct hostent *Getipnodebyname(const char *name, int af, int flags, int *error_num) { struct hostent *result; Debug4("getipnodebyname(\"%s\", %d, %d, %p)", name, af, flags, error_num); result = getipnodebyname(name, af, flags, error_num); if (result == NULL) { Debug1("getipnodebyname(,,, {%d}) -> NULL", *error_num); } else { Debug4("getipnodebyname() -> {\"%s\", %p, %d, %d, ???}", result->h_name, result->h_aliases, result->h_addrtype, result->h_length); } return result; }
static struct hostent * __gethostbyname2(const char *name, int af) { struct hostent *he; int error; if (use_ipnode_functions) { error = 0; he = getipnodebyname(name, af, ipnode_flags, &error); if (he == NULL) errno = error; } else he = gethostbyname2(name, af); return (he); }
/* * vs_eng_connect * open socket connection to remote scan engine * * Returns: sockfd or -1 (error) */ static int vs_eng_connect(char *host, int port) { int rc, sockfd, opt_nodelay, opt_keepalive, opt_reuseaddr, err_num; struct sockaddr_in addr; struct hostent *hp; if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) return (-1); hp = getipnodebyname(host, AF_INET, 0, &err_num); if (hp == NULL) { (void) close(sockfd); return (-1); } (void) memset(&addr, 0, sizeof (addr)); (void) memcpy(&addr.sin_addr, hp->h_addr, hp->h_length); addr.sin_port = htons(port); addr.sin_family = hp->h_addrtype; freehostent(hp); #ifdef FIONBIO /* Use non-blocking mode for connect. */ rc = nbio_connect(sockfd, (struct sockaddr *)&addr, sizeof (struct sockaddr)); #else rc = connect(sockfd, (struct sockaddr *)&addr, sizeof (struct sockaddr)); #endif opt_nodelay = 1; opt_keepalive = 1; opt_reuseaddr = 1; if ((rc < 0) || (setsockopt(sockfd, IPPROTO_TCP, TCP_NODELAY, &opt_nodelay, sizeof (opt_nodelay)) < 0) || (setsockopt(sockfd, SOL_SOCKET, SO_KEEPALIVE, &opt_keepalive, sizeof (opt_keepalive)) < 0) || (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &opt_reuseaddr, sizeof (opt_reuseaddr)) < 0)) { (void) close(sockfd); return (-1); } return (sockfd); }
struct hostent * tds_gethostbyname_r(const char *servername, struct hostent *result, char *buffer, int buflen, int *h_errnop) { struct hostent *he = getipnodebyname(servername, AF_INET, 0, h_errnop); if (!he) return NULL; if (tds_copy_hostent(he, result, buffer, buflen)) { errno = ENOMEM; if (h_errnop) *h_errnop = NETDB_INTERNAL; freehostent(he); return NULL; } freehostent(he); return result; }
int is_listening(char *hostname, int port) { char *uri = NULL, addr_string[INET6_ADDRSTRLEN]; struct in6_addr ipv6addr[1]; int errnum; struct hostent *hp; hp = getipnodebyname(hostname, AF_INET6, AI_ALL | AI_ADDRCONFIG | AI_V4MAPPED, &errnum); if (hp != NULL) { (void) memcpy(&ipv6addr, hp->h_addr_list[0], hp->h_length); } else return (-1); return (test_socket_access(ipv6addr, port)); }
struct hostent * tds_gethostbyname_r(const char *servername, struct hostent *result, char *buffer, int buflen, int *h_errnop) { #if defined(NETDB_REENTRANT) return gethostbyname(servername); /* we have a better replacements */ #elif defined(HAVE_GETIPNODEBYNAME) struct hostent *he = getipnodebyname(servername, AF_INET, 0, h_errnop); if (!he) return NULL; if (tds_copy_hostent(he, result, buffer, buflen)) { errno = ENOMEM; if (h_errnop) *h_errnop = NETDB_INTERNAL; freehostent(he); return NULL; } freehostent(he); return result; #elif defined(HAVE_FUNC_GETHOSTBYNAME_R_6) if (gethostbyname_r(servername, result, buffer, buflen, &result, h_errnop)) return NULL; return result; #elif defined(HAVE_FUNC_GETHOSTBYNAME_R_5) result = gethostbyname_r(servername, result, buffer, buflen, h_errnop); return result; #elif defined(HAVE_FUNC_GETHOSTBYNAME_R_3) struct hostent_data *data = (struct hostent_data *) buffer; memset(buffer, 0, buflen); if (gethostbyname_r(servername, result, data)) { *h_errnop = 0; result = NULL; } return result; #else #error gethostbyname_r style unknown #endif }
int network_connect_client(void) { struct sockaddr_in server_addr; #ifdef HAVE_IPV6 struct sockaddr_in6 server_addr6; #ifndef HAVE_GETHOSTBYNAME2 int err6; #endif #endif struct hostent *server_hostent; FILE *f; BYTE *buf; BYTE recv_buf4[4]; size_t buf_size; int return_value; if (network_init() < 0) return -1; if (network_mode != NETWORK_IDLE) return -1; vsync_suspend_speed_eval(); snapshotfilename = NULL; f = archdep_mkstemp_fd(&snapshotfilename, MODE_WRITE); if (f == NULL) { #ifdef HAS_TRANSLATION ui_error(translate_text(IDGS_CANNOT_CREATE_SNAPSHOT_S_SELECT)); #else ui_error(_("Cannot create snapshot file. Select different history directory!")); #endif return -1; } #ifdef HAVE_IPV6 if (netplay_ipv6) #ifdef HAVE_GETHOSTBYNAME2 server_hostent = gethostbyname2(server_name, PF_INET6); #else server_hostent = getipnodebyname(server_name, PF_INET6, AI_DEFAULT, &err6); #endif else
/* * call-seq: * Host.ip_addr * * Returns a list of IP addresses for the current host (yes, it is possible * to have more than one). */ static VALUE host_ip_addr(){ char host_name[MAXHOSTNAMELEN]; char str[INET6_ADDRSTRLEN]; char **pptr; struct hostent* hp; int err; VALUE v_results = rb_ary_new(); #ifndef HAVE_INET_NTOP struct in_addr ipa; int n; #endif err = gethostname(host_name, MAXHOSTNAMELEN); if(err) rb_raise(cHostError, "gethostname() call failed: %s", strerror(err)); #ifdef HAVE_GETIPNODEBYNAME hp = getipnodebyname(host_name, AF_INET, AI_DEFAULT, &err); #else hp = gethostbyname(host_name); #endif if(hp == NULL) rb_raise(cHostError, "getipnodebyname() call failed: %s", strerror(err)); pptr = hp->h_addr_list; #ifdef HAVE_INET_NTOP for( ; *pptr != NULL; pptr++){ rb_ary_push(v_results, rb_str_new2(inet_ntop(hp->h_addrtype, *pptr, str, INET6_ADDRSTRLEN))); } #else for(n = 0; hp->h_addr_list[n] != NULL; n++){ memcpy(&ipa.s_addr, hp->h_addr_list[n], hp->h_length); rb_ary_push(v_results, rb_str_new2(inet_ntoa(ipa))); } #endif return v_results; }
//----------------------------------------------------------------------------- // validate_ipstring //----------------------------------------------------------------------------- char* validate_ip_string(const char *inIPString, char *outIPString, size_t outSize) { int nErr ; char* outIP; if (!inIPString) return 0; if (!*inIPString) return 0; if (outSize < 16) return 0; // First, ask the system to look up the given name. struct hostent *hesp = getipnodebyname (inIPString, AF_INET, 0, &nErr); if (hesp == NULL) return 0; // Convert the returned info to dotted decimal string. outIP = (char*)inet_ntop(AF_INET, hesp->h_addr_list[0], outIPString, outSize); freehostent (hesp); return outIP; }
bool Ipv6Address::Resolve(const std::string& hostname,struct in6_addr& a) { if (Utility::isipv6(hostname)) { std::list<std::string> vec; size_t x = 0; for (size_t i = 0; i <= hostname.size(); i++) { if (i == hostname.size() || hostname[i] == ':') { std::string s = hostname.substr(x, i - x); // if (strstr(s.c_str(),".")) // x.x.x.x { Parse pa(s,"."); char slask[100]; // u2ip temporary hex2string conversion unsigned long b0 = static_cast<unsigned long>(pa.getvalue()); unsigned long b1 = static_cast<unsigned long>(pa.getvalue()); unsigned long b2 = static_cast<unsigned long>(pa.getvalue()); unsigned long b3 = static_cast<unsigned long>(pa.getvalue()); sprintf(slask,"%lx",b0 * 256 + b1); vec.push_back(slask); sprintf(slask,"%lx",b2 * 256 + b3); vec.push_back(slask); } else { vec.push_back(s); } // x = i + 1; } } size_t sz = vec.size(); // number of byte pairs size_t i = 0; // index in in6_addr.in6_u.u6_addr16[] ( 0 .. 7 ) for (std::list<std::string>::iterator it = vec.begin(); it != vec.end(); it++) { std::string bytepair = *it; if (bytepair.size()) { a.s6_addr16[i++] = htons(Utility::hex2unsigned(bytepair)); } else { a.s6_addr16[i++] = 0; while (sz++ < 8) { a.s6_addr16[i++] = 0; } } } return true; } #ifdef SOLARIS int errnum = 0; struct hostent *he = getipnodebyname( hostname.c_str(), AF_INET6, 0, &errnum ); #else struct hostent *he = gethostbyname2( hostname.c_str(), AF_INET6 ); #endif if (!he) { return false; } memcpy(&a,he -> h_addr_list[0],he -> h_length); #ifdef SOLARIS free(he); #endif return true; }
/* * An instance name is formed using either the host name in the fully * qualified domain name form (FQDN) which should map to a specific IP address * or using INADDR_ANY which means all IP addresses. * * We do a lookup or reverse lookup to get the host name. It is assumed that * the returned name is in the FQDN form. i.e. DNS is used. */ char * create_instance_name(const char *arg, char **inaddr_any_name, boolean_t is_create) { int len; uint16_t port; char *cname; char *instance_name; const char *prefix = "kssl-"; char *first_space; first_space = strchr(arg, ' '); if (first_space == NULL) { /* No host name. Use INADDR_ANY. */ if (get_portnum(arg, &port) == 0) { (void) fprintf(stderr, gettext("Error: Invalid port value -- %s\n"), arg); return (NULL); } KSSL_DEBUG("port=%d\n", port); if ((cname = strdup(ANY_ADDR)) == NULL) return (NULL); } else { char *temp_str; char *ptr; struct hostent *hp; boolean_t do_warn; int error_num; in_addr_t v4addr; in6_addr_t v6addr; if (get_portnum(first_space + 1, &port) == 0) { (void) fprintf(stderr, gettext("Error: Invalid port value -- %s\n"), first_space + 1); return (NULL); } KSSL_DEBUG("port=%d\n", port); if ((temp_str = strdup(arg)) == NULL) return (NULL); *(strchr(temp_str, ' ')) = '\0'; if (inet_pton(AF_INET6, temp_str, &v6addr) == 1) { /* Do a reverse lookup for the IPv6 address */ hp = getipnodebyaddr(&v6addr, sizeof (v6addr), AF_INET6, &error_num); } else if (inet_pton(AF_INET, temp_str, &v4addr) == 1) { /* Do a reverse lookup for the IPv4 address */ hp = getipnodebyaddr(&v4addr, sizeof (v4addr), AF_INET, &error_num); } else { /* Do a lookup for the host name */ hp = getipnodebyname(temp_str, AF_INET6, AI_DEFAULT, &error_num); } if (hp == NULL) { (void) fprintf(stderr, gettext("Error: Unknown host -- %s\n"), temp_str); free(temp_str); return (NULL); } if ((ptr = cname = strdup(hp->h_name)) == NULL) { freehostent(hp); free(temp_str); return (NULL); } freehostent(hp); do_warn = B_TRUE; /* "s/./-/g" */ while ((ptr = strchr(ptr, '.')) != NULL) { if (do_warn) do_warn = B_FALSE; *ptr = '-'; ptr++; } if (do_warn && is_create) { (void) fprintf(stderr, gettext("Warning: %s does not appear to have a" " registered DNS name.\n"), temp_str); } free(temp_str); } KSSL_DEBUG("Cannonical host name =%s\n", cname); len = strlen(prefix) + strlen(cname) + 10; if ((instance_name = malloc(len)) == NULL) { (void) fprintf(stderr, gettext("Error: memory allocation failure.\n")); return (NULL); } (void) snprintf(instance_name, len, "%s%s-%d", prefix, cname, port); if (is_create) { len = strlen(prefix) + strlen(ANY_ADDR) + 10; if ((*inaddr_any_name = malloc(len)) == NULL) { (void) fprintf(stderr, gettext("Error: memory allocation failure.\n")); free(instance_name); free(cname); return (NULL); } (void) snprintf(*inaddr_any_name, len, "%s%s-%d", prefix, ANY_ADDR, port); } free(cname); KSSL_DEBUG("instance_name=%s\n", instance_name); return (instance_name); }
/* * parsehosts() end parses the host string (hosts_str) */ static auditd_rc_t parsehosts(char *hosts_str, char **error) { char *hostportmech, *hpm; char *hostname; char *port_str; char *mech_str; int port; int port_default = -1; gss_OID mech_oid; char *lasts_hpm; hostlist_t *lasthost = NULL; hostlist_t *hosts_new = NULL; hostlist_t *newhost; struct hostent *hostentry; int error_num; int rc; #if DEBUG char addr_buf[INET6_ADDRSTRLEN]; int num_of_hosts = 0; #endif DPRINT((dfile, "parsing %s\n", hosts_str)); while ((hostportmech = strtok_r(hosts_str, ",", &lasts_hpm)) != NULL) { hosts_str = NULL; hostname = NULL; port_str = NULL; port = port_default; mech_str = NULL; mech_oid = GSS_C_NO_OID; DPRINT((dfile, "parsing host:port:mech %s\n", hostportmech)); if (strncmp(hostportmech, ":", 1 == 0)) { /* ":port:" case */ *error = strdup(gettext("no hostname specified")); return (AUDITD_INVALID); } /* parse single host:port:mech target */ while ((hpm = strsep(&hostportmech, ":")) != NULL) { if (hostname == NULL) { hostname = hpm; continue; } if (port_str == NULL) { port_str = hpm; continue; } if (mech_str == NULL) { mech_str = hpm; continue; } /* too many colons in the hostportmech string */ *error = strdup(gettext("invalid host:port:mech " "specification")); return (AUDITD_INVALID); } if (hostname == NULL || *hostname == '\0') { *error = strdup(gettext("invalid hostname " "specification")); return (AUDITD_INVALID); } /* trim hostname */ hostname = trim_me(hostname); if (hostname == NULL || *hostname == '\0') { *error = strdup(gettext("empty hostname " "specification")); return (AUDITD_INVALID); } DPRINT((dfile, "resolving address for %s\n", hostname)); hostentry = getipnodebyname(hostname, AF_INET6, 0, &error_num); if (!hostentry) { hostentry = getipnodebyname(hostname, AF_INET, 0, &error_num); } if (!hostentry) { if (error_num == TRY_AGAIN) { *error = strdup(gettext("host not found, " "try later")); return (AUDITD_RETRY); } else { *error = strdup(gettext("host not found")); return (AUDITD_INVALID); } } DPRINT((dfile, "hostentry: h_name=%s, addr_len=%d, addr=%s\n", hostentry->h_name, hostentry->h_length, inet_ntop(hostentry->h_addrtype, hostentry->h_addr_list[0], addr_buf, INET6_ADDRSTRLEN))); /* trim port */ port_str = trim_me(port_str); if (port_str == NULL || *port_str == '\0') { if (port_default == -1 && (rc = get_port_default(&port_default)) != AUDITD_SUCCESS) { *error = strdup(gettext( "unable to get default port number")); return (rc); } port = port_default; DPRINT((dfile, "port: %d (default)\n", port)); } else { errno = 0; port = atoi(port_str); if (errno != 0 || port < 1 || port > USHRT_MAX) { *error = strdup(gettext("invalid port number")); return (AUDITD_INVALID); } DPRINT((dfile, "port: %d\n", port)); } /* trim mechanism */ mech_str = trim_me(mech_str); if (mech_str != NULL && *mech_str != '\0') { if (rpc_gss_mech_to_oid(mech_str, &mech_oid) != TRUE) { *error = strdup(gettext("unknown mechanism")); return (AUDITD_INVALID); } DPRINT((dfile, "mechanism: %s\n", mech_str)); #if DEBUG } else { DPRINT((dfile, "mechanism: null (default)\n")); #endif } /* add this host to host list */ newhost = malloc(sizeof (hostlist_t)); if (newhost == NULL) { *error = strdup(gettext("no memory")); return (AUDITD_NO_MEMORY); } newhost->host = hostentry; newhost->port = htons(port); newhost->mech = mech_oid; newhost->next_host = NULL; if (lasthost != NULL) { lasthost->next_host = newhost; lasthost = lasthost->next_host; } else { lasthost = newhost; hosts_new = newhost; } #if DEBUG num_of_hosts++; #endif } (void) pthread_mutex_lock(&plugin_mutex); if (hosts_prev == NULL) { hosts_prev = hosts; } hosts = hosts_new; current_host = hosts; (void) pthread_mutex_unlock(&plugin_mutex); DPRINT((dfile, "Configured %d hosts.\n", num_of_hosts)); return (AUDITD_SUCCESS); }
int netsnmp_sockaddr_in6_2 (struct sockaddr_in6 *addr, const char *inpeername, const char *default_target) { char *cp = NULL, *peername = NULL; char debug_addr[INET6_ADDRSTRLEN]; #if HAVE_GETADDRINFO struct addrinfo *addrs = NULL; int err; #elif HAVE_GETIPNODEBYNAME struct hostent *hp = NULL; int err; #elif HAVE_GETHOSTBYNAME struct hostent *hp = NULL; #endif int portno; if (addr == NULL) { return 0; } DEBUGMSGTL (("netsnmp_sockaddr_in6", "addr %p, peername \"%s\", default_target \"%s\"\n", addr, inpeername ? inpeername : "[NIL]", default_target ? default_target : "[NIL]")); memset (addr, 0, sizeof (struct sockaddr_in6)); addr->sin6_family = AF_INET6; addr->sin6_addr = in6addr_any; addr->sin6_port = htons ((u_short) SNMP_PORT); { int port = netsnmp_ds_get_int (NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_DEFAULT_PORT); if (port != 0) addr->sin6_port = htons ((u_short) port); else if (default_target != NULL) netsnmp_sockaddr_in6_2 (addr, default_target, NULL); } if (inpeername != NULL) { /* * Duplicate the peername because we might want to mank around with * it. */ peername = strdup (inpeername); if (peername == NULL) { return 0; } for (cp = peername; *cp && isdigit ((unsigned char) *cp); cp++); portno = atoi (peername); if (!*cp && portno != 0) { /* * Okay, it looks like JUST a port number. */ DEBUGMSGTL (("netsnmp_sockaddr_in6", "totally numeric: %d\n", portno)); addr->sin6_port = htons ((u_short) portno); goto resolved; } /* * See if it is an IPv6 address covered with square brackets. Also check * for an appended :port. */ if (*peername == '[') { cp = strchr (peername, ']'); if (cp != NULL) { /* * See if it is an IPv6 link-local address with interface * name as <zone_id>, like fe80::1234%eth0. * Please refer to the internet draft, IPv6 Scoped Address Architecture * http://www.ietf.org/internet-drafts/draft-ietf-ipngwg-scoping-arch-04.txt * */ char *scope_id; unsigned int if_index = 0; *cp = '\0'; scope_id = strchr (peername + 1, '%'); if (scope_id != NULL) { *scope_id = '\0'; if_index = netsnmp_if_nametoindex (scope_id + 1); } if (*(cp + 1) == ':') { portno = atoi (cp + 2); if (portno != 0 && inet_pton (AF_INET6, peername + 1, (void *) &(addr->sin6_addr))) { DEBUGMSGTL (("netsnmp_sockaddr_in6", "IPv6 address with port suffix :%d\n", portno)); if (portno > 0 && portno < 0xffff) { addr->sin6_port = htons ((u_short) portno); } else { DEBUGMSGTL (("netsnmp_sockaddr_in6", "invalid port number: %d", portno)); return 0; } #if defined(HAVE_STRUCT_SOCKADDR_IN6_SIN6_SCOPE_ID) addr->sin6_scope_id = if_index; #endif goto resolved; } } else { if (inet_pton (AF_INET6, peername + 1, (void *) &(addr->sin6_addr))) { DEBUGMSGTL (("netsnmp_sockaddr_in6", "IPv6 address with square brackets\n")); portno = netsnmp_ds_get_int (NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_DEFAULT_PORT); if (portno <= 0) portno = SNMP_PORT; addr->sin6_port = htons ((u_short) portno); #if defined(HAVE_STRUCT_SOCKADDR_IN6_SIN6_SCOPE_ID) addr->sin6_scope_id = if_index; #endif goto resolved; } } if (scope_id != NULL) { *scope_id = '%'; } *cp = ']'; } } cp = strrchr (peername, ':'); if (cp != NULL) { char *scope_id; unsigned int if_index = 0; *cp = '\0'; scope_id = strchr (peername + 1, '%'); if (scope_id != NULL) { *scope_id = '\0'; if_index = netsnmp_if_nametoindex (scope_id + 1); } portno = atoi (cp + 1); if (portno != 0 && inet_pton (AF_INET6, peername, (void *) &(addr->sin6_addr))) { DEBUGMSGTL (("netsnmp_sockaddr_in6", "IPv6 address with port suffix :%d\n", atoi (cp + 1))); if (portno > 0 && portno < 0xffff) { addr->sin6_port = htons ((u_short) portno); } else { DEBUGMSGTL (("netsnmp_sockaddr_in6", "invalid port number: %d", portno)); return 0; } #if defined(HAVE_STRUCT_SOCKADDR_IN6_SIN6_SCOPE_ID) addr->sin6_scope_id = if_index; #endif goto resolved; } if (scope_id != NULL) { *scope_id = '%'; } *cp = ':'; } /* * See if it is JUST an IPv6 address. */ if (inet_pton (AF_INET6, peername, (void *) &(addr->sin6_addr))) { DEBUGMSGTL (("netsnmp_sockaddr_in6", "just IPv6 address\n")); goto resolved; } /* * Well, it must be a hostname then, possibly with an appended :port. * Sort that out first. */ cp = strrchr (peername, ':'); if (cp != NULL) { *cp = '\0'; portno = atoi (cp + 1); if (portno != 0) { DEBUGMSGTL (("netsnmp_sockaddr_in6", "hostname(?) with port suffix :%d\n", portno)); if (portno > 0 && portno < 0xffff) { addr->sin6_port = htons ((u_short) portno); } else { DEBUGMSGTL (("netsnmp_sockaddr_in6", "invalid port number: %d", portno)); return 0; } } else { /* * No idea, looks bogus but we might as well pass the full thing to * the name resolver below. */ *cp = ':'; DEBUGMSGTL (("netsnmp_sockaddr_in6", "hostname(?) with embedded ':'?\n")); } /* * Fall through. */ } if (peername[0] == '\0') { DEBUGMSGTL (("netsnmp_sockaddr_in6", "empty hostname\n")); free (peername); return 0; } #if HAVE_GETADDRINFO { struct addrinfo hint = { 0 }; hint.ai_flags = 0; hint.ai_family = PF_INET6; hint.ai_socktype = SOCK_DGRAM; hint.ai_protocol = 0; err = netsnmp_getaddrinfo (peername, NULL, &hint, &addrs); } if (err != 0) { #if HAVE_GAI_STRERROR snmp_log (LOG_ERR, "getaddrinfo(\"%s\", NULL, ...): %s\n", peername, gai_strerror (err)); #else snmp_log (LOG_ERR, "getaddrinfo(\"%s\", NULL, ...): (error %d)\n", peername, err); #endif free (peername); return 0; } if (addrs != NULL) { DEBUGMSGTL (("netsnmp_sockaddr_in6", "hostname (resolved okay)\n")); memcpy (&addr->sin6_addr, &((struct sockaddr_in6 *) addrs->ai_addr)->sin6_addr, sizeof (struct in6_addr)); freeaddrinfo (addrs); } else { DEBUGMSGTL (("netsnmp_sockaddr_in6", "Failed to resolve IPv6 hostname\n")); } #elif HAVE_GETIPNODEBYNAME hp = getipnodebyname (peername, AF_INET6, 0, &err); if (hp == NULL) { DEBUGMSGTL (("netsnmp_sockaddr_in6", "hostname (couldn't resolve = %d)\n", err)); free (peername); return 0; } DEBUGMSGTL (("netsnmp_sockaddr_in6", "hostname (resolved okay)\n")); memcpy (&(addr->sin6_addr), hp->h_addr, hp->h_length); #elif HAVE_GETHOSTBYNAME hp = netsnmp_gethostbyname (peername); if (hp == NULL) { DEBUGMSGTL (("netsnmp_sockaddr_in6", "hostname (couldn't resolve)\n")); free (peername); return 0; } else { if (hp->h_addrtype != AF_INET6) { DEBUGMSGTL (("netsnmp_sockaddr_in6", "hostname (not AF_INET6!)\n")); free (peername); return 0; } else { DEBUGMSGTL (("netsnmp_sockaddr_in6", "hostname (resolved okay)\n")); memcpy (&(addr->sin6_addr), hp->h_addr, hp->h_length); } } #else /*HAVE_GETHOSTBYNAME */ /* * There is no name resolving function available. */ snmp_log (LOG_ERR, "no getaddrinfo()/getipnodebyname()/gethostbyname()\n"); free (peername); return 0; #endif /*HAVE_GETHOSTBYNAME */ } else { DEBUGMSGTL (("netsnmp_sockaddr_in6", "NULL peername")); return 0; } resolved: DEBUGMSGTL (("netsnmp_sockaddr_in6", "return { AF_INET6, [%s]:%hu }\n", inet_ntop (AF_INET6, &addr->sin6_addr, debug_addr, sizeof (debug_addr)), ntohs (addr->sin6_port))); free (peername); return 1; }
struct libnet_in6_addr libnet_name2addr6(libnet_t *l, char *host_name, u_int8_t use_name) { #if !defined (__WIN32__) struct libnet_in6_addr addr; struct hostent *host_ent; #endif if (use_name == LIBNET_RESOLVE) { #ifdef __WIN32__ /* XXX - we don't support this yet */ if (l) { snprintf(l->err_buf, LIBNET_ERRBUF_SIZE, "%s(): can't resolve IPv6 addresses\n", __func__); } return (in6addr_error); #else #ifdef HAVE_SOLARIS #ifdef HAVE_SOLARIS_IPV6 if (!(host_ent = getipnodebyname((int8_t *)&addr, sizeof(struct in_addr), AF_INET6, NULL))) #else snprintf(l->err_buf, LIBNET_ERRBUF_SIZE, "%s(): %s\n", __func__, strerror(errno)); return (in6addr_error); #endif #else if (!(host_ent = gethostbyname2(host_name, AF_INET6))) #endif { snprintf(l->err_buf, LIBNET_ERRBUF_SIZE, "%s(): %s", __func__, strerror(errno)); return (in6addr_error); } memcpy(&addr, host_ent->h_addr, host_ent->h_length); return (addr); #endif /* !__WIN32__ */ } else { #if defined(__WIN32__) /* Silence Win32 warning */ if (l) { snprintf(l->err_buf, LIBNET_ERRBUF_SIZE, "%s(): can't resolve IPv6 addresses.\n", __func__); } return (in6addr_error); #else if(!inet_pton(AF_INET6, host_name, &addr)) { if (l) { snprintf(l->err_buf, LIBNET_ERRBUF_SIZE, "%s(): invalid IPv6 address\n", __func__); } return (in6addr_error); } return (addr); #endif } }
//----------------------------------------------------------------------------- // process_server_prefs //----------------------------------------------------------------------------- static int process_server_prefs(struct vpn_params *params) { u_int32_t lval, len; u_char str[MAXPATHLEN]; int err ; struct hostent *hostent; get_int_option(params->serverRef, kRASEntServer, kRASPropServerMaximumSessions, &lval, 0); if (lval) params->max_sessions = lval; len = sizeof(str); get_str_option(params->serverRef, kRASEntServer, kRASPropServerLogfile, str, sizeof(str), &len, (u_char*)default_log_path); if (str[0]) memcpy(params->log_path, str, len + 1); get_int_option(params->serverRef, kRASEntServer, kRASPropServerVerboseLogging, &lval, 0); if (lval) params->log_verbose = lval; // Load balancing parameters get_int_option(params->serverRef, kRASEntServer, kRASPropServerLoadBalancingEnabled, &lval, 0); if (lval) { params->lb_enable = 1; // will determine the interface from the cluster address //len = sizeof(str); //get_str_option(params->serverRef, kRASEntServer, kRASPropServerLoadBalancingInterface, str, sizeof(str), &len, "en1"); //strncpy(params->lb_interface, str, sizeof(params->lb_interface)); // is priority really useful ? //get_int_option(params->serverRef, kRASEntServer, kRASPropServerLoadBalancingPriority, &lval, 5); //if (lval < 1) lval = 1; //else if (lval > LB_MAX_PRIORITY) lval = LB_MAX_PRIORITY; //params->lb_priority = lval; get_int_option(params->serverRef, kRASEntServer, kRASPropServerLoadBalancingPort, &lval, LB_DEFAULT_PORT); params->lb_port = htons(lval); len = sizeof(str); get_str_option(params->serverRef, kRASEntServer, kRASPropServerLoadBalancingAddress, str, sizeof(str), &len, empty_str); // ask the system to look up the given name. hostent = getipnodebyname ((char*)str, AF_INET, 0, &err); if (!hostent) { vpnlog(LOG_ERR, "Incorrect Load Balancing address found '%s'\n", str); params->lb_enable = 0; } else { struct sockaddr_in src, dst; params->lb_cluster_address = *(struct in_addr *)hostent->h_addr_list[0]; freehostent(hostent); bzero(&dst, sizeof(dst)); dst.sin_family = PF_INET; dst.sin_len = sizeof(dst); dst.sin_addr = params->lb_cluster_address; // look for the interface and primary address of the cluster address if (get_route_interface((struct sockaddr *)&src, (struct sockaddr *)&dst, params->lb_interface)) { vpnlog(LOG_ERR, "Cannot get load balancing redirect address and interface (errno = %d)\n", errno); params->lb_enable = 0; } params->lb_redirect_address = src.sin_addr; } } return 0; }
/* XXX: should be deprecated */ struct hostent * getnodebyname(const char *name, int af, int flags) { return getipnodebyname(name, af, flags, &h_errno); }
int netsnmp_gethostbyname_v4(const char* name, in_addr_t *addr_out) { #if HAVE_GETADDRINFO struct addrinfo *addrs = NULL; struct addrinfo hint; int err; memset(&hint, 0, sizeof hint); hint.ai_flags = 0; hint.ai_family = PF_INET; hint.ai_socktype = SOCK_DGRAM; hint.ai_protocol = 0; err = netsnmp_getaddrinfo(name, NULL, &hint, &addrs); if (err != 0) { return -1; } if (addrs != NULL) { memcpy(addr_out, &((struct sockaddr_in *) addrs->ai_addr)->sin_addr, sizeof(in_addr_t)); freeaddrinfo(addrs); } else { DEBUGMSGTL(("get_thisaddr", "Failed to resolve IPv4 hostname\n")); } return 0; #elif HAVE_GETHOSTBYNAME struct hostent *hp = NULL; hp = netsnmp_gethostbyname(name); if (hp == NULL) { DEBUGMSGTL(("get_thisaddr", "hostname (couldn't resolve)\n")); return -1; } else if (hp->h_addrtype != AF_INET) { DEBUGMSGTL(("get_thisaddr", "hostname (not AF_INET!)\n")); return -1; } else { DEBUGMSGTL(("get_thisaddr", "hostname (resolved okay)\n")); memcpy(addr_out, hp->h_addr, sizeof(in_addr_t)); } return 0; #elif HAVE_GETIPNODEBYNAME struct hostent *hp = NULL; int err; hp = getipnodebyname(peername, AF_INET, 0, &err); if (hp == NULL) { DEBUGMSGTL(("get_thisaddr", "hostname (couldn't resolve = %d)\n", err)); return -1; } DEBUGMSGTL(("get_thisaddr", "hostname (resolved okay)\n")); memcpy(addr_out, hp->h_addr, sizeof(in_addr_t)); return 0; #else /* HAVE_GETIPNODEBYNAME */ return -1; #endif }
int main(int argc, char *argv[]) { int mib[4] = { CTL_NET, PF_INET6, IPPROTO_IPV6, IPV6CTL_DEFHLIM }; char hbuf[NI_MAXHOST], src0[NI_MAXHOST], *ep; int ch, i, on = 1, seq, rcvcmsglen, error, minlen; struct addrinfo hints, *res; static u_char *rcvcmsgbuf; u_long probe, hops, lport; struct hostent *hp; size_t size; uid_t uid; /* * Receive ICMP */ if ((rcvsock = socket(AF_INET6, SOCK_RAW, IPPROTO_ICMPV6)) < 0) { perror("socket(ICMPv6)"); exit(5); } /* revoke privs */ uid = getuid(); if (setresuid(uid, uid, uid) == -1) err(1, "setresuid"); size = sizeof(i); (void) sysctl(mib, sizeof(mib)/sizeof(mib[0]), &i, &size, NULL, 0); max_hops = i; /* specify to tell receiving interface */ if (setsockopt(rcvsock, IPPROTO_IPV6, IPV6_RECVPKTINFO, &on, sizeof(on)) < 0) err(1, "setsockopt(IPV6_RECVPKTINFO)"); /* specify to tell value of hoplimit field of received IP6 hdr */ if (setsockopt(rcvsock, IPPROTO_IPV6, IPV6_RECVHOPLIMIT, &on, sizeof(on)) < 0) err(1, "setsockopt(IPV6_RECVHOPLIMIT)"); seq = 0; while ((ch = getopt(argc, argv, "df:g:Ilm:np:q:rs:w:v")) != -1) switch (ch) { case 'd': options |= SO_DEBUG; break; case 'f': ep = NULL; errno = 0; first_hop = strtoul(optarg, &ep, 0); if (errno || !*optarg || *ep|| first_hop > 255) { fprintf(stderr, "traceroute6: invalid min hoplimit.\n"); exit(1); } break; case 'g': hp = getipnodebyname(optarg, AF_INET6, 0, &h_errno); if (hp == NULL) { fprintf(stderr, "traceroute6: unknown host %s\n", optarg); exit(1); } if (rth == NULL) { /* * XXX: We can't detect the number of * intermediate nodes yet. */ if ((rth = inet6_rth_init((void *)rtbuf, sizeof(rtbuf), IPV6_RTHDR_TYPE_0, 0)) == NULL) { fprintf(stderr, "inet6_rth_init failed.\n"); exit(1); } } if (inet6_rth_add((void *)rth, (struct in6_addr *)hp->h_addr)) { fprintf(stderr, "inet6_rth_add failed for %s\n", optarg); exit(1); } freehostent(hp); break; case 'I': useicmp++; ident = htons(getpid() & 0xffff); /* same as ping6 */ break; case 'l': lflag++; break; case 'm': ep = NULL; errno = 0; max_hops = strtoul(optarg, &ep, 0); if (errno || !*optarg || *ep || max_hops > 255) { fprintf(stderr, "traceroute6: invalid max hoplimit.\n"); exit(1); } break; case 'n': nflag++; break; case 'p': ep = NULL; errno = 0; lport = strtoul(optarg, &ep, 0); if (errno || !*optarg || *ep) { fprintf(stderr, "traceroute6: invalid port.\n"); exit(1); } if (lport == 0 || lport != (lport & 0xffff)) { fprintf(stderr, "traceroute6: port out of range.\n"); exit(1); } port = lport & 0xffff; break; case 'q': ep = NULL; errno = 0; nprobes = strtoul(optarg, &ep, 0); if (errno || !*optarg || *ep) { fprintf(stderr, "traceroute6: invalid nprobes.\n"); exit(1); } if (nprobes < 1) { fprintf(stderr, "traceroute6: nprobes must be >0.\n"); exit(1); } break; case 'r': options |= SO_DONTROUTE; break; case 's': /* * set the ip source address of the outbound * probe (e.g., on a multi-homed host). */ source = optarg; break; case 'v': verbose++; break; case 'w': ep = NULL; errno = 0; waittime = strtoul(optarg, &ep, 0); if (errno || !*optarg || *ep) { fprintf(stderr, "traceroute6: invalid wait time.\n"); exit(1); } if (waittime <= 1) { fprintf(stderr, "traceroute6: wait must be >1 sec.\n"); exit(1); } break; default: usage(); } argc -= optind; argv += optind; if (max_hops < first_hop) { fprintf(stderr, "traceroute6: max hoplimit must be larger than first hoplimit.\n"); exit(1); } if (argc < 1 || argc > 2) usage(); #if 1 setvbuf(stdout, NULL, _IOLBF, BUFSIZ); #else setlinebuf(stdout); #endif memset(&hints, 0, sizeof(hints)); hints.ai_family = PF_INET6; hints.ai_socktype = SOCK_RAW; hints.ai_protocol = IPPROTO_ICMPV6; hints.ai_flags = AI_CANONNAME; error = getaddrinfo(*argv, NULL, &hints, &res); if (error) { fprintf(stderr, "traceroute6: %s\n", gai_strerror(error)); exit(1); } if (res->ai_addrlen != sizeof(Dst)) { fprintf(stderr, "traceroute6: size of sockaddr mismatch\n"); exit(1); } memcpy(&Dst, res->ai_addr, res->ai_addrlen); hostname = res->ai_canonname ? strdup(res->ai_canonname) : *argv; if (!hostname) { fprintf(stderr, "traceroute6: not enough core\n"); exit(1); } if (res->ai_next) { if (getnameinfo(res->ai_addr, res->ai_addrlen, hbuf, sizeof(hbuf), NULL, 0, NI_NUMERICHOST) != 0) strlcpy(hbuf, "?", sizeof(hbuf)); fprintf(stderr, "traceroute6: Warning: %s has multiple " "addresses; using %s\n", hostname, hbuf); } if (*++argv) { ep = NULL; errno = 0; datalen = strtoul(*argv, &ep, 0); if (errno || !*argv || *ep) { fprintf(stderr, "traceroute6: invalid packet length.\n"); exit(1); } } if (useicmp) minlen = ICMP6ECHOLEN + sizeof(struct tv32); else minlen = sizeof(struct opacket); if (datalen < minlen) datalen = minlen; else if (datalen >= MAXPACKET) { fprintf(stderr, "traceroute6: packet size must be %d <= s < %ld.\n", minlen, (long)MAXPACKET); exit(1); } outpacket = (struct opacket *)malloc((unsigned)datalen); if (!outpacket) { perror("malloc"); exit(1); } (void) bzero((char *)outpacket, datalen); /* initialize msghdr for receiving packets */ rcviov[0].iov_base = (caddr_t)packet; rcviov[0].iov_len = sizeof(packet); rcvmhdr.msg_name = (caddr_t)&Rcv; rcvmhdr.msg_namelen = sizeof(Rcv); rcvmhdr.msg_iov = rcviov; rcvmhdr.msg_iovlen = 1; rcvcmsglen = CMSG_SPACE(sizeof(struct in6_pktinfo)) + CMSG_SPACE(sizeof(int)); if ((rcvcmsgbuf = malloc(rcvcmsglen)) == NULL) { fprintf(stderr, "traceroute6: malloc failed\n"); exit(1); } rcvmhdr.msg_control = (caddr_t) rcvcmsgbuf; rcvmhdr.msg_controllen = rcvcmsglen; if (options & SO_DEBUG) (void) setsockopt(rcvsock, SOL_SOCKET, SO_DEBUG, (char *)&on, sizeof(on)); if (options & SO_DONTROUTE) (void) setsockopt(rcvsock, SOL_SOCKET, SO_DONTROUTE, (char *)&on, sizeof(on)); /* * Send UDP or ICMP */ if (useicmp) { sndsock = rcvsock; } else { if ((sndsock = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) { perror("socket(SOCK_DGRAM)"); exit(5); } } #ifdef SO_SNDBUF i = datalen; if (setsockopt(sndsock, SOL_SOCKET, SO_SNDBUF, (char *)&i, sizeof(i)) < 0) { perror("setsockopt(SO_SNDBUF)"); exit(6); } #endif /* SO_SNDBUF */ if (options & SO_DEBUG) (void) setsockopt(sndsock, SOL_SOCKET, SO_DEBUG, (char *)&on, sizeof(on)); if (options & SO_DONTROUTE) (void) setsockopt(sndsock, SOL_SOCKET, SO_DONTROUTE, (char *)&on, sizeof(on)); if (rth) {/* XXX: there is no library to finalize the header... */ rth->ip6r_len = rth->ip6r_segleft * 2; if (setsockopt(sndsock, IPPROTO_IPV6, IPV6_RTHDR, (void *)rth, (rth->ip6r_len + 1) << 3)) { fprintf(stderr, "setsockopt(IPV6_RTHDR): %s\n", strerror(errno)); exit(1); } } /* * Source selection */ bzero(&Src, sizeof(Src)); if (source) { struct addrinfo hints, *res; int error; memset(&hints, 0, sizeof(hints)); hints.ai_family = AF_INET6; hints.ai_socktype = SOCK_DGRAM; /*dummy*/ hints.ai_flags = AI_NUMERICHOST; error = getaddrinfo(source, "0", &hints, &res); if (error) { printf("traceroute6: %s: %s\n", source, gai_strerror(error)); exit(1); } if (res->ai_addrlen > sizeof(Src)) { printf("traceroute6: %s: %s\n", source, gai_strerror(error)); exit(1); } memcpy(&Src, res->ai_addr, res->ai_addrlen); freeaddrinfo(res); } else { struct sockaddr_in6 Nxt; int dummy; socklen_t len; Nxt = Dst; Nxt.sin6_port = htons(DUMMY_PORT); if (cmsg != NULL) bcopy(inet6_rthdr_getaddr(cmsg, 1), &Nxt.sin6_addr, sizeof(Nxt.sin6_addr)); if ((dummy = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) { perror("socket"); exit(1); } if (connect(dummy, (struct sockaddr *)&Nxt, Nxt.sin6_len) < 0) { perror("connect"); exit(1); } len = sizeof(Src); if (getsockname(dummy, (struct sockaddr *)&Src, &len) < 0) { perror("getsockname"); exit(1); } if (getnameinfo((struct sockaddr *)&Src, Src.sin6_len, src0, sizeof(src0), NULL, 0, NI_NUMERICHOST)) { fprintf(stderr, "getnameinfo failed for source\n"); exit(1); } source = src0; close(dummy); } Src.sin6_port = htons(0); if (bind(sndsock, (struct sockaddr *)&Src, Src.sin6_len) < 0) { perror("bind"); exit(1); } { socklen_t len; len = sizeof(Src); if (getsockname(sndsock, (struct sockaddr *)&Src, &len) < 0) { perror("getsockname"); exit(1); } srcport = ntohs(Src.sin6_port); } /* * Message to users */ if (getnameinfo((struct sockaddr *)&Dst, Dst.sin6_len, hbuf, sizeof(hbuf), NULL, 0, NI_NUMERICHOST)) strlcpy(hbuf, "(invalid)", sizeof(hbuf)); fprintf(stderr, "traceroute6"); fprintf(stderr, " to %s (%s)", hostname, hbuf); if (source) fprintf(stderr, " from %s", source); fprintf(stderr, ", %lu hops max, %lu byte packets\n", max_hops, datalen); (void) fflush(stderr); if (first_hop > 1) printf("Skipping %lu intermediate hops\n", first_hop - 1); /* * Main loop */ for (hops = first_hop; hops <= max_hops; ++hops) { struct in6_addr lastaddr; int got_there = 0; int unreachable = 0; printf("%2lu ", hops); bzero(&lastaddr, sizeof(lastaddr)); for (probe = 0; probe < nprobes; ++probe) { int cc; struct timeval t1, t2; (void) gettimeofday(&t1, NULL); send_probe(++seq, hops); while ((cc = wait_for_reply(rcvsock, &rcvmhdr))) { (void) gettimeofday(&t2, NULL); if ((i = packet_ok(&rcvmhdr, cc, seq))) { if (!IN6_ARE_ADDR_EQUAL(&Rcv.sin6_addr, &lastaddr)) { print(&rcvmhdr, cc); lastaddr = Rcv.sin6_addr; } printf(" %g ms", deltaT(&t1, &t2)); switch (i - 1) { case ICMP6_DST_UNREACH_NOROUTE: ++unreachable; printf(" !N"); break; case ICMP6_DST_UNREACH_ADMIN: ++unreachable; printf(" !P"); break; case ICMP6_DST_UNREACH_NOTNEIGHBOR: ++unreachable; printf(" !S"); break; case ICMP6_DST_UNREACH_ADDR: ++unreachable; printf(" !A"); break; case ICMP6_DST_UNREACH_NOPORT: if (rcvhlim >= 0 && rcvhlim <= 1) printf(" !"); ++got_there; break; } break; } } if (cc == 0) printf(" *"); (void) fflush(stdout); } putchar('\n'); if (got_there || (unreachable > 0 && unreachable >= ((nprobes + 1) / 2))) { exit(0); } } exit(0); }
/* * NAME: conn->init() * DESCRIPTION: initialize connection handling */ bool conn_init(int maxusers, char **thosts, char **bhosts, unsigned short *tports, unsigned short *bports, int ntports, int nbports) { # ifdef INET6 struct sockaddr_in6 sin6; # endif struct sockaddr_in sin; struct hostent *host; int n; connection *conn; bool ipv6, ipv4; int err; if (!ipa_init(maxusers)) { return FALSE; } #ifdef NETWORK_EXTENSIONS addrtype = PF_INET; #endif nusers = 0; maxfd = 0; FD_ZERO(&infds); FD_ZERO(&outfds); FD_ZERO(&waitfds); FD_SET(in, &infds); npackets = 0; closed = 0; #ifndef NETWORK_EXTENSIONS ntdescs = ntports; if (ntports != 0) { tdescs = ALLOC(portdesc, ntports); memset(tdescs, -1, ntports * sizeof(portdesc)); } nbdescs = nbports; if (nbports != 0) { bdescs = ALLOC(portdesc, nbports); memset(bdescs, -1, nbports * sizeof(portdesc)); udescs = ALLOC(portdesc, nbports); memset(udescs, -1, nbports * sizeof(portdesc)); } #endif # ifdef INET6 memset(&sin6, '\0', sizeof(sin6)); sin6.sin6_family = AF_INET6; # endif memset(&sin, '\0', sizeof(sin)); sin.sin_family = AF_INET; for (n = 0; n < ntdescs; n++) { /* telnet ports */ ipv6 = FALSE; ipv4 = FALSE; if (thosts[n] == (char *) NULL) { # ifdef INET6 sin6.sin6_addr = in6addr_any; ipv6 = TRUE; # endif sin.sin_addr.s_addr = INADDR_ANY; ipv4 = TRUE; } else { # ifdef INET6 if (inet_pton(AF_INET6, thosts[n], &sin6) > 0) { ipv6 = TRUE; } else { # ifdef AI_DEFAULT host = getipnodebyname(thosts[n], AF_INET6, 0, &err); if (host != (struct hostent *) NULL) { memcpy(&sin6.sin6_addr, host->h_addr, host->h_length); ipv6 = TRUE; freehostent(host); } # else host = gethostbyname2(thosts[n], AF_INET6); if (host != (struct hostent *) NULL) { memcpy(&sin6.sin6_addr, host->h_addr, host->h_length); ipv6 = TRUE; } # endif } # endif if ((sin.sin_addr.s_addr=inet_addr(thosts[n])) != INADDR_NONE) { ipv4 = TRUE; } else { host = gethostbyname(thosts[n]); if (host != (struct hostent *) NULL) { memcpy(&sin.sin_addr, host->h_addr, host->h_length); ipv4 = TRUE; } } } if (!ipv6 && !ipv4) { message("unknown host %s\012", thosts[n]); /* LF */ return FALSE; } # ifdef INET6 if (ipv6 && !conn_port6(&tdescs[n].in6, SOCK_STREAM, &sin6, tports[n])) { return FALSE; } # endif if (ipv4 && !conn_port(&tdescs[n].in4, SOCK_STREAM, &sin, tports[n])) { return FALSE; } } for (n = 0; n < nbdescs; n++) { /* binary ports */ ipv6 = FALSE; ipv4 = FALSE; if (bhosts[n] == (char *) NULL) { # ifdef INET6 sin6.sin6_addr = in6addr_any; ipv6 = TRUE; # endif sin.sin_addr.s_addr = INADDR_ANY; ipv4 = TRUE; } else { # ifdef INET6 if (inet_pton(AF_INET6, bhosts[n], &sin6) > 0) { ipv6 = TRUE; } else { # ifdef AI_DEFAULT host = getipnodebyname(bhosts[n], AF_INET6, 0, &err); if (host != (struct hostent *) NULL) { memcpy(&sin6.sin6_addr, host->h_addr, host->h_length); ipv6 = TRUE; freehostent(host); } # else host = gethostbyname2(bhosts[n], AF_INET6); if (host != (struct hostent *) NULL) { memcpy(&sin6.sin6_addr, host->h_addr, host->h_length); ipv6 = TRUE; } # endif } # endif if ((sin.sin_addr.s_addr=inet_addr(bhosts[n])) != INADDR_NONE) { ipv4 = TRUE; } else { host = gethostbyname(bhosts[n]); if (host != (struct hostent *) NULL) { memcpy(&sin.sin_addr, host->h_addr, host->h_length); ipv4 = TRUE; } } } if (!ipv6 && !ipv4) { message("unknown host %s\012", bhosts[n]); /* LF */ return FALSE; } # ifdef INET6 if (ipv6) { if (!conn_port6(&bdescs[n].in6, SOCK_STREAM, &sin6, bports[n])) { return FALSE; } if (!conn_port6(&udescs[n].in6, SOCK_DGRAM, &sin6, bports[n])) { return FALSE; } } # endif if (ipv4) { if (!conn_port(&bdescs[n].in4, SOCK_STREAM, &sin, bports[n])) { return FALSE; } if (!conn_port(&udescs[n].in4, SOCK_DGRAM, &sin, bports[n])) { return FALSE; } } } flist = (connection *) NULL; #ifndef NETWORK_EXTENSIONS connections = ALLOC(connection, nusers = maxusers); #else connections = ALLOC(connection, nusers = maxusers+1); #endif for (n = nusers, conn = connections; n > 0; --n, conn++) { conn->fd = -1; conn->chain.next = (hte *) flist; flist = conn; } #ifndef NETWORK_EXTENSIONS udphtab = ALLOC(connection*, udphtabsz = maxusers); memset(udphtab, '\0', udphtabsz * sizeof(connection*)); chtab = ht_new(maxusers, UDPHASHSZ, TRUE); #endif return TRUE; }