const char* condor_sockaddr::to_ip_string(char* buf, int len) const { if ( is_ipv4() ) return inet_ntop(AF_INET, &v4.sin_addr, buf, len); else if (is_ipv6()) { // [m] Special Case for IPv4-mapped-IPv6 string // certain implementation such as IpVerify internally uses // IPv6 format to store all IP addresses. // Although they use IPv6 address, they rely on // IPv4-style text representation. // for example, IPv4-mapped-IPv6 string will be shown as // a form of '::ffff:a.b.c.d', however they need // 'a.b.c.d' // // These reliance should be corrected at some point. // hopefully, at IPv6-Phase3 const uint32_t* addr = (const uint32_t*)&v6.sin6_addr; if (addr[0] == 0 && addr[1] == 0 && addr[2] == ntohl(0xffff)) { return inet_ntop(AF_INET, (const void*)&addr[3], buf, len); } return inet_ntop(AF_INET6, &v6.sin6_addr, buf, len); } else { snprintf(buf, len, "%x INVALID ADDRESS FAMILY", (unsigned int)v4.sin_family); return NULL; } }
int condor_sockaddr::get_aftype() const { if (is_ipv4()) return AF_INET; else if (is_ipv6()) return AF_INET6; return AF_UNSPEC; }
socklen_t condor_sockaddr::get_socklen() const { if (is_ipv4()) return sizeof(sockaddr_in); else if (is_ipv6()) return sizeof(sockaddr_in6); else return sizeof(sockaddr_storage); }
int main_is_ipv6(const char* progname, const int argc, const char **argv){ int i = 0; if(argc<2) help_is_ipv6(); int r = is_ipv6(argv[1]); return r; }
void condor_sockaddr::set_addr_any() { if (is_ipv4()) { v4.sin_addr.s_addr = ntohl(INADDR_ANY); } else if (is_ipv6()) { v6.sin6_addr = in6addr_any; } }
// IN6_* macro are came from netinet/inet.h // need to check whether it is platform-independent macro // -- compiled on every unix/linux platforms bool condor_sockaddr::is_addr_any() const { if (is_ipv4()) { return v4.sin_addr.s_addr == ntohl(INADDR_ANY); } else if (is_ipv6()) { return IN6_IS_ADDR_UNSPECIFIED(&v6.sin6_addr); } return false; }
bool condor_sockaddr::is_link_local() const { if (is_ipv4()) { // it begins with 169.254 -> a9 fe uint32_t mask = 0xa9fe0000; return ((uint32_t)v4.sin_addr.s_addr & mask) == mask; } else if (is_ipv6()) { // it begins with fe80 return v6.sin6_addr.s6_addr[0] == 0xfe && v6.sin6_addr.s6_addr[1] == 0x80; } return false; }
in6_addr condor_sockaddr::to_ipv6_address() const { if (is_ipv6()) return v6.sin6_addr; in6_addr ret; memset(&ret, 0, sizeof(ret)); // the field name of struct in6_addr is differ from platform to // platform. thus, we use a pointer. uint32_t* addr = (uint32_t*)&ret; addr[0] = 0; addr[1] = 0; addr[2] = htonl(0xffff); addr[3] = v4.sin_addr.s_addr; return ret; }
bool condor_sockaddr::compare_address(const condor_sockaddr& addr) const { if (is_ipv4()) { if (!addr.is_ipv4()) return false; return v4.sin_addr.s_addr == addr.v4.sin_addr.s_addr; } else if (is_ipv6()) { if (!addr.is_ipv6()) return false; return memcmp((const void*)&v6.sin6_addr, (const void*)&addr.v6.sin6_addr, sizeof(in6_addr)) == 0; } return false; }
const char* condor_sockaddr::to_sinful(char* buf, int len) const { char tmp[IP_STRING_BUF_SIZE]; // if it is not ipv4 or ipv6, to_ip_string_ex will fail. if ( !to_ip_string_ex(tmp, IP_STRING_BUF_SIZE) ) return NULL; if (is_ipv4()) { snprintf(buf, len, "<%s:%d>", tmp, ntohs(v4.sin_port)); } else if (is_ipv6()) { snprintf(buf, len, "<[%s]:%d>", tmp, ntohs(v6.sin6_port)); } return buf; }
MyString condor_sockaddr::to_sinful() const { MyString ret; char tmp[IP_STRING_BUF_SIZE]; // if it is not ipv4 or ipv6, to_ip_string_ex will fail. if ( !to_ip_string_ex(tmp, IP_STRING_BUF_SIZE) ) return ret; if (is_ipv4()) { ret.formatstr("<%s:%d>", tmp, ntohs(v4.sin_port)); } else if (is_ipv6()) { ret.formatstr("<[%s]:%d>", tmp, ntohs(v6.sin6_port)); } return ret; }
bool condor_sockaddr::is_link_local() const { if (is_ipv4()) { static struct in_addr link_mask; static bool initialized = false; if(!initialized) { int converted = inet_pton(AF_INET, "169.254.0.0", &link_mask); ASSERT(converted); initialized = true; } return ((uint32_t)v4.sin_addr.s_addr & link_mask.s_addr) == link_mask.s_addr; } else if (is_ipv6()) { // it begins with fe80 return v6.sin6_addr.s6_addr[0] == 0xfe && v6.sin6_addr.s6_addr[1] == 0x80; } return false; }
bool condor_sockaddr::is_private_network() const { if (is_ipv4()) { static bool initialized = false; static condor_netaddr p10; static condor_netaddr p172_16; static condor_netaddr p192_168; if(!initialized) { p10.from_net_string("10.0.0.0/8"); p172_16.from_net_string("172.16.0.0/12"); p192_168.from_net_string("192.168.0.0/16"); initialized = true; } return p10.match(*this) || p172_16.match(*this) || p192_168.match(*this); } else if (is_ipv6()) { return IN6_IS_ADDR_LINKLOCAL(&v6.sin6_addr); } else { } return false; }
/************************************************************************************************** CONF_SET_RECURSIVE If the 'recursive' configuration option was specified, set the recursive server. **************************************************************************************************/ static void conf_set_recursive(void) { char *c; const char *address = conf_get(&Conf, "recursive", NULL); char addr[512]; int port = 53; if (!address || !address[0]) return; strncpy(addr, address, sizeof(addr)-1); #if HAVE_IPV6 if (is_ipv6(addr)) { /* IPv6 - treat '+' as port separator */ recursive_family = AF_INET6; if ((c = strchr(addr, '+'))) { *c++ = '\0'; if (!(port = atoi(c))) port = 53; } if (inet_pton(AF_INET6, addr, &recursive_sa6.sin6_addr) <= 0) { Warnx("%s: %s", address, _("invalid network address for recursive server")); return; } recursive_sa6.sin6_family = AF_INET6; recursive_sa6.sin6_port = htons(port); forward_recursive = 1; #if DEBUG_ENABLED && DEBUG_CONF DebugX("conf", 1,_("recursive forwarding service through %s:%u"), ipaddr(AF_INET6, &recursive_sa6.sin6_addr), port); #endif recursive_fwd_server = STRDUP(address); } else { /* IPv4 - treat '+' or ':' as port separator */ #endif recursive_family = AF_INET; if ((c = strchr(addr, '+')) || (c = strchr(addr, ':'))) { *c++ = '\0'; if (!(port = atoi(c))) port = 53; } if (inet_pton(AF_INET, addr, &recursive_sa.sin_addr) <= 0) { Warnx("%s: %s", address, _("invalid network address for recursive server")); return; } recursive_sa.sin_family = AF_INET; recursive_sa.sin_port = htons(port); #if DEBUG_ENABLED &&DEBUG_CONF DebugX("conf", 1,_("recursive forwarding service through %s:%u"), ipaddr(AF_INET, &recursive_sa.sin_addr), port); #endif forward_recursive = 1; recursive_fwd_server = STRDUP(address); #if HAVE_IPV6 } #endif if (!forward_recursive) return; recursion_timeout = atou(conf_get(&Conf, "recursive-timeout", NULL)); recursion_connect_timeout = atou(conf_get(&Conf, "recursive-connect-timeout", NULL)); recursion_retries = atou(conf_get(&Conf, "recursive-retries", NULL)); recursion_algorithm = conf_get(&Conf, "recursive-algorithm", NULL); }
void process_ip_header (struct context *c, unsigned int flags, struct buffer *buf) { if (!c->options.ce.mssfix) flags &= ~PIP_MSSFIX; #if PASSTOS_CAPABILITY if (!c->options.passtos) flags &= ~PIPV4_PASSTOS; #endif if (!c->options.route_gateway_via_dhcp) flags &= ~PIPV4_EXTRACT_DHCP_ROUTER; if (buf->len > 0) { /* * The --passtos and --mssfix options require * us to examine the IPv4 header. */ #if PASSTOS_CAPABILITY if (flags & (PIPV4_PASSTOS|PIP_MSSFIX)) #else if (flags & PIP_MSSFIX) #endif { struct buffer ipbuf = *buf; if (is_ipv4 (TUNNEL_TYPE (c->c1.tuntap), &ipbuf)) { #if PASSTOS_CAPABILITY /* extract TOS from IP header */ if (flags & PIPV4_PASSTOS) link_socket_extract_tos (c->c2.link_socket, &ipbuf); #endif /* possibly alter the TCP MSS */ if (flags & PIP_MSSFIX) mss_fixup_ipv4 (&ipbuf, MTU_TO_MSS (TUN_MTU_SIZE_DYNAMIC (&c->c2.frame))); #ifdef ENABLE_CLIENT_NAT /* possibly do NAT on packet */ if ((flags & PIPV4_CLIENT_NAT) && c->options.client_nat) { const int direction = (flags & PIPV4_OUTGOING) ? CN_INCOMING : CN_OUTGOING; client_nat_transform (c->options.client_nat, &ipbuf, direction); } #endif /* possibly extract a DHCP router message */ if (flags & PIPV4_EXTRACT_DHCP_ROUTER) { const in_addr_t dhcp_router = dhcp_extract_router_msg (&ipbuf); if (dhcp_router) route_list_add_vpn_gateway (c->c1.route_list, c->c2.es, dhcp_router); } } else if (is_ipv6 (TUNNEL_TYPE (c->c1.tuntap), &ipbuf)) { /* possibly alter the TCP MSS */ if (flags & PIP_MSSFIX) mss_fixup_ipv6 (&ipbuf, MTU_TO_MSS (TUN_MTU_SIZE_DYNAMIC (&c->c2.frame))); } } } }
void condor_sockaddr::set_scope_id(uint32_t scope_id) { if (!is_ipv6()) return; v6.sin6_scope_id = scope_id; }
static struct ftp_connection_info *add_file_cmd_to_str(struct connection *c) { unsigned char *d = get_url_data(c->url); unsigned char *de; int del; unsigned char port_string[50]; struct ftp_connection_info *inf, *inf2; unsigned char *s; int l; if (!d) { internal("get_url_data failed"); setcstate(c, S_INTERNAL); abort_connection(c); return NULL; } de = init_str(), del = 0; add_conv_str(&de, &del, d, strlen(cast_const_char d), -2); d = de; inf = mem_alloc(sizeof(struct ftp_connection_info)); memset(inf, 0, sizeof(struct ftp_connection_info)); l = 0; s = init_str(); inf->pasv = ftp_options.passive_ftp; #ifdef LINKS_2 if (*c->socks_proxy) inf->pasv = 1; if (ftp_options.eprt_epsv || is_ipv6(c->sock1)) inf->eprt_epsv = 1; #endif c->info = inf; if (!inf->pasv) { int ps; #ifdef SUPPORT_IPV6 if (is_ipv6(c->sock1)) { ps = get_pasv_socket_ipv6(c, c->sock1, &c->sock2, port_string); if (ps) { mem_free(d); mem_free(s); return NULL; } } else #endif { unsigned char pc[6]; ps = get_pasv_socket(c, c->sock1, &c->sock2, pc); if (ps) { mem_free(d); mem_free(s); return NULL; } if (inf->eprt_epsv) sprintf(cast_char port_string, "|1|%d.%d.%d.%d|%d|", pc[0], pc[1], pc[2], pc[3], (pc[4] << 8) | pc[5]); else sprintf(cast_char port_string, "%d,%d,%d,%d,%d,%d", pc[0], pc[1], pc[2], pc[3], pc[4], pc[5]); } if (strlen(cast_const_char port_string) >= sizeof(port_string)) internal("buffer overflow in get_pasv_socket_ipv6: %d > %d", (int)strlen(cast_const_char port_string), (int)sizeof(port_string)); } #ifdef HAVE_IPTOS if (ftp_options.set_tos) { int rx; int on = IPTOS_THROUGHPUT; EINTRLOOP(rx, setsockopt(c->sock2, IPPROTO_IP, IP_TOS, (char *)&on, sizeof(int))); } #endif if (!(de = cast_uchar strchr(cast_const_char d, POST_CHAR))) de = d + strlen(cast_const_char d); if (d == de || de[-1] == '/') { inf->dir = 1; inf->pending_commands = 4; add_to_str(&s, &l, cast_uchar "TYPE A\r\n"); add_port_pasv(&s, &l, inf, port_string); add_to_str(&s, &l, cast_uchar "CWD /"); add_bytes_to_str(&s, &l, d, de - d); add_to_str(&s, &l, cast_uchar "\r\nLIST\r\n"); c->from = 0; } else { inf->dir = 0; inf->pending_commands = 3; add_to_str(&s, &l, cast_uchar "TYPE I\r\n"); add_port_pasv(&s, &l, inf, port_string); if (c->from && c->no_cache < NC_IF_MOD) { add_to_str(&s, &l, cast_uchar "REST "); add_num_to_str(&s, &l, c->from); add_to_str(&s, &l, cast_uchar "\r\n"); inf->rest_sent = 1; inf->pending_commands++; } else c->from = 0; add_to_str(&s, &l, cast_uchar "RETR /"); add_bytes_to_str(&s, &l, d, de - d); add_to_str(&s, &l, cast_uchar "\r\n"); } inf->opc = inf->pending_commands; if ((unsigned)l > MAXINT - sizeof(struct ftp_connection_info) - 1) overalloc(); inf2 = mem_realloc(inf, sizeof(struct ftp_connection_info) + l + 1); strcpy(cast_char (inf = inf2)->cmdbuf, cast_const_char s); mem_free(s); c->info = inf; mem_free(d); return inf; }