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; } }
/* Helper, prints a formatted ipaddr to stream. */ static int __printf_ipaddr(FILE *stream, uint8_t *ipaddr) { int i, j, eln, eli; int ret = 0; uint16_t s; if (is_ipv4(ipaddr)) return fprintf(stream, "%d.%d.%d.%d", ipaddr[12], ipaddr[13], ipaddr[14], ipaddr[15]); /* find longest elision */ eln = eli = -1; for (i = 0; i < 16; i += 2) { for (j = i; j < 16; j += 2) if (ipaddr[j] != 0 || ipaddr[j + 1] != 0) break; if (j > i && j - i > eln) { eli = i; eln = j - i; } } /* print with possible elision */ for (i = 0; i < 16; i += 2) { if (i == eli) { ret += fprintf(stream, "::"); i += eln; if (i >= 16) break; } else if (i != 0) ret += fprintf(stream, ":"); s = (ipaddr[i] << 8) + ipaddr[i + 1]; ret += fprintf(stream, "%x", s); } return ret; }
int condor_sockaddr::get_aftype() const { if (is_ipv4()) return AF_INET; else if (is_ipv6()) return AF_INET6; return AF_UNSPEC; }
int main(int argc, char *argv[]) { ssize_t n; char *line = NULL; char *ip_addr; size_t size = 32; FILE *fp; const char *filename = argv[1]; fp = fopen(filename, "r"); if (!fp) { fprintf(stderr, "Error in opening the file!\n"); exit(1); } while ((n = getline(&line, &size, fp)) != -1) { if (line[n-1] == '\n') { line[n-1] = '\0'; ip_addr = (char *) malloc(n-2); strncpy(ip_addr, line, n-2); } else { ip_addr = (char *) malloc(n); strncpy(ip_addr, line, n); } printf("Is '%s' valid IPv4? \n%s\n", ip_addr, is_ipv4(ip_addr)); } fclose(fp); return(0); }
bool condor_sockaddr::is_loopback() const { if (is_ipv4()) { return ((v4.sin_addr.s_addr & 0xFF) == 0x7F); // 127/8 } else { return IN6_IS_ADDR_LOOPBACK( &v6.sin6_addr ); } }
void condor_sockaddr::set_port(unsigned short port) { if (is_ipv4()) { v4.sin_port = htons(port); } else { v6.sin6_port = htons(port); } }
void condor_sockaddr::set_loopback() { if (is_ipv4()) { v4.sin_addr.s_addr = ntohl(INADDR_LOOPBACK); } else { v6.sin6_addr = in6addr_loopback; } }
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; } }
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); }
unsigned short condor_sockaddr::get_port() const { if (is_ipv4()) { return ntohs(v4.sin_port); } else { return ntohs(v6.sin6_port); } }
void process_ipv4_header (struct context *c, unsigned int flags, struct buffer *buf) { if (!c->options.ce.mssfix) flags &= ~PIPV4_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|PIPV4_MSSFIX)) #else if (flags & PIPV4_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 & PIPV4_MSSFIX) mss_fixup (&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); } } } } }
// 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; }
c_ip46_addr::c_ip46_addr(const std::string &ip_addr, int port) { // ports-TODO(r) also parse the port here // TODO parsing ipv6 if (is_ipv4(ip_addr)) { (*this) = create_ipv4(ip_addr, port); } else { (*this) = create_ipv6(ip_addr, port); } _info("Parsing ip46 from string ["<<ip_addr<<":" << port << "] created: " << (*this)); }
void condor_sockaddr::convert_to_ipv6() { // only ipv4 addressn can be converted if (!is_ipv4()) return; in6_addr addr = to_ipv6_address(); unsigned short port = get_port(); clear(); set_ipv6(); set_port(port); v6.sin6_addr = addr; }
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; }
void ipv4_packet_size_verify(const uint8_t *data, const int size, const int tunnel_type, const char *prefix, counter_type *errors) { if (size > 0) { struct buffer buf; buf_set_read(&buf, data, size); if (is_ipv4(tunnel_type, &buf)) { const struct openvpn_iphdr *pip; int hlen; int totlen; const char *msgstr = "PACKET SIZE INFO"; unsigned int msglevel = D_PACKET_TRUNC_DEBUG; if (BLEN(&buf) < (int) sizeof(struct openvpn_iphdr)) { return; } verify_align_4(&buf); pip = (struct openvpn_iphdr *) BPTR(&buf); hlen = OPENVPN_IPH_GET_LEN(pip->version_len); totlen = ntohs(pip->tot_len); if (BLEN(&buf) != totlen) { msgstr = "PACKET TRUNCATION ERROR"; msglevel = D_PACKET_TRUNC_ERR; if (errors) { ++(*errors); } } msg(msglevel, "%s %s: size=%d totlen=%d hlen=%d errcount=" counter_format, msgstr, prefix, BLEN(&buf), totlen, hlen, errors ? *errors : (counter_type)0); } } }
sockaddr_storage condor_sockaddr::to_storage() const { sockaddr_storage tmp; if (is_ipv4()) { memcpy(&tmp, &v4, sizeof(v4)); } else { memcpy(&tmp, &v6, sizeof(v6)); } return tmp; }
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; }
void process_ipv4_header (struct context *c, unsigned int flags, struct buffer *buf) { if (!c->options.mssfix) flags &= ~PIPV4_MSSFIX; #if PASSTOS_CAPABILITY if (!c->options.passtos) flags &= ~PIPV4_PASSTOS; #endif if (!c->options.route_gateway_via_dhcp || !route_list_default_gateway_needed (c->c1.route_list)) 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|PIPV4_MSSFIX)) #else if (flags & PIPV4_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 & PIPV4_MSSFIX) mss_fixup (&ipbuf, MTU_TO_MSS (TUN_MTU_SIZE_DYNAMIC (&c->c2.frame))); /* possibly extract a DHCP router message */ if (flags & PIPV4_EXTRACT_DHCP_ROUTER) { const in_addr_t dhcp_router = dhcp_extract_router_msg (&ipbuf); route_list_add_default_gateway (c->c1.route_list, c->c2.es, dhcp_router); } } } } }
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; }
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; }
IP_Address::operator String() const { if (!valid) return ""; if (is_ipv4()) // IPv4 address mapped to IPv6 return itos(field8[12]) + "." + itos(field8[13]) + "." + itos(field8[14]) + "." + itos(field8[15]); String ret; for (int i = 0; i < 8; i++) { if (i > 0) ret = ret + ":"; uint16_t num = (field8[i * 2] << 8) + field8[i * 2 + 1]; ret = ret + String::num_int64(num, 16); }; return ret; }
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; }
void assign_if_set(dct_ip_address_v4_t& dct_address, const HAL_IPAddress* address) { if (address && is_ipv4(address)) { dct_address = address->ipv4; } }
int main(int argc, char *const argv[]) { int verbose = 0; int character; char *fname = NULL; while ((character = getopt(argc, argv, "vf:")) != -1) { switch (character) { case 'v': verbose = 1; break; case 'f': fname = strdup(optarg); break; default: case '?': usage(argv[0]); } } argc -= optind; argv += optind; if (!fname) { fname = strdup(TMMDB_DEFAULT_DATABASE); } assert(fname != NULL); //TMMDB_s *mmdb = TMMDB_open(fname, TMMDB_MODE_MEMORY_CACHE); TMMDB_s *mmdb; int err = TMMDB_open(&mmdb, fname, TMMDB_MODE_STANDARD); if (err != TMMDB_SUCCESS) { fprintf(stderr, "Can't open %s ( %d )\n", fname, err); exit(1); } free(fname); char *ipstr = argv[0]; union { struct in_addr v4; struct in6_addr v6; } ip; int ai_family = is_ipv4(mmdb) ? AF_INET : AF_INET6; int ai_flags = AI_V4MAPPED; if (ipstr == NULL || 0 != TMMDB_resolve_address(ipstr, ai_family, ai_flags, &ip)) { fprintf(stderr, "Invalid IP\n"); exit(1); } if (verbose) { dump_meta(mmdb); } TMMDB_root_entry_s root = {.entry.mmdb = mmdb }; int status = is_ipv4(mmdb) ? TMMDB_lookup_by_ipnum(htonl(ip.v4.s_addr), &root) : TMMDB_lookup_by_ipnum_128(ip.v6, &root); if (status == TMMDB_SUCCESS) { if (root.entry.offset > 0) { TMMDB_decode_all_s *decode_all; int err = TMMDB_get_tree(&root.entry, &decode_all); if (err == TMMDB_SUCCESS) { if (decode_all != NULL) TMMDB_dump(mmdb, decode_all, 0); TMMDB_free_decode_all(decode_all); } } else { puts("Sorry, nothing found"); // not found } } return (0); }
const uint8_t *IP_Address::get_ipv4() const { ERR_FAIL_COND_V(!is_ipv4(), 0); return &(field8[12]); }
int main(int argc, char *const argv[]) { int verbose = 0; int character; char *fname = NULL; while ((character = getopt(argc, argv, "vf:")) != -1) { switch (character) { case 'v': verbose = 1; break; case 'f': fname = strdup(optarg); break; default: case '?': usage(argv[0]); } } argc -= optind; argv += optind; if (!fname) { fname = strdup(MMDB_DEFAULT_DATABASE); } assert(fname != NULL); //MMDB_s *mmdb = MMDB_open(fname, MMDB_MODE_MEMORY_CACHE); MMDB_s *mmdb = MMDB_open(fname, MMDB_MODE_STANDARD); if (!mmdb) die("Can't open %s\n", fname); free(fname); char *ipstr = argv[0]; union { struct in_addr v4; struct in6_addr v6; } ip; int ai_family = is_ipv4(mmdb) ? AF_INET : AF_INET6; int ai_flags = AI_V4MAPPED; // accept everything if (ipstr == NULL || 0 != MMDB_resolve_address(ipstr, ai_family, ai_flags, &ip)) { fprintf(stderr, "Invalid IP\n"); exit(1); } if (verbose) { dump_meta(mmdb); } MMDB_root_entry_s root = {.entry.mmdb = mmdb }; int status = is_ipv4(mmdb) ? MMDB_lookup_by_ipnum(htonl(ip.v4.s_addr), &root) : MMDB_lookup_by_ipnum_128(ip.v6, &root); if (status == MMDB_SUCCESS) { dump_ipinfo(ipstr, &root); } return (0); }