static SilcBool silc_net_set_sockaddr(SilcSockaddr *addr, const char *ip_addr, int port) { int len; memset(addr, 0, sizeof(*addr)); /* Check for IPv4 and IPv6 addresses */ if (ip_addr) { if (!silc_net_is_ip(ip_addr)) { SILC_LOG_ERROR(("%s is not IP address", ip_addr)); return FALSE; } if (silc_net_is_ip4(ip_addr)) { /* IPv4 address */ len = sizeof(addr->sin.sin_addr); silc_net_addr2bin(ip_addr, (unsigned char *)&addr->sin.sin_addr.s_addr, len); addr->sin.sin_family = AF_INET; addr->sin.sin_port = port ? htons(port) : 0; } else { #ifdef HAVE_IPV6 /* IPv6 address */ len = sizeof(addr->sin6.sin6_addr); silc_net_addr2bin(ip_addr, (unsigned char *)&addr->sin6.sin6_addr, len); addr->sin6.sin6_family = AF_INET6; addr->sin6.sin6_port = port ? htons(port) : 0; #else SILC_LOG_ERROR(("IPv6 support is not compiled in")); return FALSE; #endif } } else { /* Any address */ addr->sin.sin_family = AF_INET; addr->sin.sin_addr.s_addr = INADDR_ANY; if (port) addr->sin.sin_port = htons(port); } return TRUE; }
gboolean silcpurple_ip_is_private(const char *ip) { if (silc_net_is_ip4(ip)) { if (!strncmp(ip, "10.", 3)) { return TRUE; } else if (!strncmp(ip, "172.", 4) && strlen(ip) > 6) { char tmp[3]; int s; memset(tmp, 0, sizeof(tmp)); strncpy(tmp, ip + 4, 2); s = atoi(tmp); if (s >= 16 && s <= 31) return TRUE; } else if (!strncmp(ip, "192.168.", 8)) { return TRUE; } } return FALSE; }
SilcBool silc_net_addr2bin(const char *addr, void *bin, SilcUInt32 bin_len) { int ret = 0; if (silc_net_is_ip4(addr)) { /* IPv4 address */ struct in_addr tmp; ret = inet_aton(addr, &tmp); if (bin_len < 4) return FALSE; memcpy(bin, (unsigned char *)&tmp.s_addr, 4); #ifdef HAVE_IPV6 } else { struct addrinfo hints, *ai; SilcSockaddr *s; /* IPv6 address */ if (bin_len < 16) return FALSE; memset(&hints, 0, sizeof(hints)); hints.ai_family = AF_INET6; if (getaddrinfo(addr, NULL, &hints, &ai)) return FALSE; if (ai) { s = (SilcSockaddr *)ai->ai_addr; memcpy(bin, &s->sin6.sin6_addr, sizeof(s->sin6.sin6_addr)); freeaddrinfo(ai); } ret = TRUE; #endif /* HAVE_IPV6 */ } return ret != 0; }
static SilcBool silc_net_set_sockaddr(TInetAddr *addr, const char *ip_addr, int port) { /* Check for IPv4 and IPv6 addresses */ if (ip_addr) { if (!silc_net_is_ip(ip_addr)) { SILC_LOG_ERROR(("%s is not IP address", ip_addr)); return FALSE; } if (silc_net_is_ip4(ip_addr)) { /* IPv4 address */ unsigned char buf[4]; TUint32 a; if (!silc_net_addr2bin(ip_addr, buf, sizeof(buf))) return FALSE; SILC_GET32_MSB(a, buf); addr->SetAddress(a); addr->SetPort(port); } else { #ifdef HAVE_IPV6 SILC_LOG_ERROR(("IPv6 not supported")); return FALSE; #else SILC_LOG_ERROR(("Operating System does not support IPv6")); return FALSE; #endif } } else { addr->SetAddress(0); addr->SetPort(port); } return TRUE; }
SilcBool silc_net_gethostbyname(const char *name, SilcBool prefer_ipv6, char *address, SilcUInt32 address_len) { #ifdef HAVE_IPV6 struct addrinfo hints, *ai, *tmp, *ip4 = NULL, *ip6 = NULL; memset(&hints, 0, sizeof(hints)); hints.ai_socktype = SOCK_STREAM; if (getaddrinfo(name, NULL, &hints, &ai)) return FALSE; for (tmp = ai; tmp; tmp = tmp->ai_next) { if (tmp->ai_family == AF_INET6) { ip6 = tmp; if (ip4) break; continue; } if (tmp->ai_family == AF_INET) { ip4 = tmp; if (ip6) break; continue; } } tmp = (prefer_ipv6 ? (ip6 ? ip6 : ip4) : (ip4 ? ip4 : ip6)); if (!tmp) { freeaddrinfo(ai); return FALSE; } if (getnameinfo(tmp->ai_addr, tmp->ai_addrlen, address, address_len, NULL, 0, NI_NUMERICHOST)) { freeaddrinfo(ai); return FALSE; } freeaddrinfo(ai); #else struct hostent *hp; struct in_addr ip; char *tmp; if (silc_net_is_ip4(name)) { memset(address, 0, address_len); if (address_len < strlen(name)) return FALSE; strncpy(address, name, strlen(name)); return TRUE; } hp = gethostbyname(name); if (!hp) return FALSE; memcpy(&ip.s_addr, hp->h_addr_list[0], 4); tmp = inet_ntoa(ip); if (!tmp) return FALSE; if (address_len < strlen(tmp)) return FALSE; memset(address, 0, address_len); strncpy(address, tmp, strlen(tmp)); #endif return TRUE; }
SilcBool silc_net_is_ip(const char *addr) { if (silc_net_is_ip4(addr)) return TRUE; return silc_net_is_ip6(addr); }