END_TEST START_TEST(test_ip_equal) { int res; IP ip1, ip2; ip_reset(&ip1); ip_reset(&ip2); res = ip_equal(NULL, NULL); ck_assert_msg(res == 0, "ip_equal(NULL, NULL): expected result 0, got %u.", res); res = ip_equal(&ip1, NULL); ck_assert_msg(res == 0, "ip_equal(PTR, NULL): expected result 0, got %u.", res); res = ip_equal(NULL, &ip1); ck_assert_msg(res == 0, "ip_equal(NULL, PTR): expected result 0, got %u.", res); ip1.family = AF_INET; ip1.ip4.uint32 = net_htonl(0x7F000001); res = ip_equal(&ip1, &ip2); ck_assert_msg(res == 0, "ip_equal( {AF_INET, 127.0.0.1}, {AF_UNSPEC, 0} ): expected result 0, got %u.", res); ip2.family = AF_INET; ip2.ip4.uint32 = net_htonl(0x7F000001); res = ip_equal(&ip1, &ip2); ck_assert_msg(res != 0, "ip_equal( {AF_INET, 127.0.0.1}, {AF_INET, 127.0.0.1} ): expected result != 0, got 0."); ip2.ip4.uint32 = net_htonl(0x7F000002); res = ip_equal(&ip1, &ip2); ck_assert_msg(res == 0, "ip_equal( {AF_INET, 127.0.0.1}, {AF_INET, 127.0.0.2} ): expected result 0, got %u.", res); ip2.family = AF_INET6; ip2.ip6.uint32[0] = 0; ip2.ip6.uint32[1] = 0; ip2.ip6.uint32[2] = net_htonl(0xFFFF); ip2.ip6.uint32[3] = net_htonl(0x7F000001); ck_assert_msg(IPV6_IPV4_IN_V6(ip2.ip6) != 0, "IPV6_IPV4_IN_V6(::ffff:127.0.0.1): expected != 0, got 0."); res = ip_equal(&ip1, &ip2); ck_assert_msg(res != 0, "ip_equal( {AF_INET, 127.0.0.1}, {AF_INET6, ::ffff:127.0.0.1} ): expected result != 0, got 0."); memcpy(&ip2.ip6, &in6addr_loopback, sizeof(IP6)); res = ip_equal(&ip1, &ip2); ck_assert_msg(res == 0, "ip_equal( {AF_INET, 127.0.0.1}, {AF_INET6, ::1} ): expected result 0, got %u.", res); memcpy(&ip1, &ip2, sizeof(IP)); res = ip_equal(&ip1, &ip2); ck_assert_msg(res != 0, "ip_equal( {AF_INET6, ::1}, {AF_INET6, ::1} ): expected result != 0, got 0."); ip2.ip6.uint8[15]++; res = ip_equal(&ip1, &ip2); ck_assert_msg(res == 0, "ip_equal( {AF_INET6, ::1}, {AF_INET6, ::2} ): expected result 0, got %res.", res); }
int bootstrap_set_callbacks(Networking_Core *net, uint32_t version, uint8_t *motd, uint16_t motd_length) { if (motd_length > MAX_MOTD_LENGTH) { return -1; } bootstrap_version = net_htonl(version); memcpy(bootstrap_motd, motd, motd_length); bootstrap_motd_length = motd_length; networking_registerhandler(net, BOOTSTRAP_INFO_PACKET_ID, &handle_info_request, net); return 0; }
END_TEST static void increment_nonce_number_cmp(uint8_t *nonce, uint32_t num) { uint32_t num1, num2; memcpy(&num1, nonce + (CRYPTO_NONCE_SIZE - sizeof(num1)), sizeof(num1)); num1 = net_ntohl(num1); num2 = num + num1; if (num2 < num1) { for (uint16_t i = CRYPTO_NONCE_SIZE - sizeof(num1); i != 0; --i) { ++nonce[i - 1]; if (nonce[i - 1] != 0) { break; } } } num2 = net_htonl(num2); memcpy(nonce + (CRYPTO_NONCE_SIZE - sizeof(num2)), &num2, sizeof(num2)); }
/* * Create a listening socket on bind_ip:port */ int net_bind( int *fd, const char *bind_ip, int port ) { int n, c[4]; struct sockaddr_in server_addr; #if defined(_WIN32) || defined(_WIN32_WCE) || defined(_WIN32_WP8) WSADATA wsaData; if( wsa_init_done == 0 ) { if( WSAStartup( MAKEWORD(2,0), &wsaData ) == SOCKET_ERROR ) return( POLARSSL_ERR_NET_SOCKET_FAILED ); wsa_init_done = 1; } #else signal( SIGPIPE, SIG_IGN ); #endif if( ( *fd = socket( AF_INET, SOCK_STREAM, IPPROTO_IP ) ) < 0 ) return( POLARSSL_ERR_NET_SOCKET_FAILED ); n = 1; setsockopt( *fd, SOL_SOCKET, SO_REUSEADDR, (const char *) &n, sizeof( n ) ); server_addr.sin_addr.s_addr = net_htonl( INADDR_ANY ); server_addr.sin_family = AF_INET; server_addr.sin_port = net_htons( port ); if( bind_ip != NULL ) { memset( c, 0, sizeof( c ) ); sscanf( bind_ip, "%d.%d.%d.%d", &c[0], &c[1], &c[2], &c[3] ); for( n = 0; n < 4; n++ ) if( c[n] < 0 || c[n] > 255 ) break; if( n == 4 ) server_addr.sin_addr.s_addr = net_htonl( ( (uint32_t) c[0] << 24 ) | ( (uint32_t) c[1] << 16 ) | ( (uint32_t) c[2] << 8 ) | ( (uint32_t) c[3] ) ); } if( bind( *fd, (struct sockaddr *) &server_addr, sizeof( server_addr ) ) < 0 ) { close( *fd ); return( POLARSSL_ERR_NET_BIND_FAILED ); } if( listen( *fd, POLARSSL_NET_LISTEN_BACKLOG ) != 0 ) { close( *fd ); return( POLARSSL_ERR_NET_LISTEN_FAILED ); } return( 0 ); }
static void fetch_broadcast_info(uint16_t port) { IP_ADAPTER_INFO *pAdapterInfo = (IP_ADAPTER_INFO *)malloc(sizeof(IP_ADAPTER_INFO)); unsigned long ulOutBufLen = sizeof(IP_ADAPTER_INFO); if (pAdapterInfo == nullptr) { return; } if (GetAdaptersInfo(pAdapterInfo, &ulOutBufLen) == ERROR_BUFFER_OVERFLOW) { free(pAdapterInfo); pAdapterInfo = (IP_ADAPTER_INFO *)malloc(ulOutBufLen); if (pAdapterInfo == nullptr) { return; } } /* We copy these to the static variables broadcast_* only at the end of fetch_broadcast_info(). * The intention is to ensure that even if multiple threads enter fetch_broadcast_info() concurrently, only valid * interfaces will be set to be broadcast to. * */ int count = 0; IP_Port ip_ports[MAX_INTERFACES]; int ret; if ((ret = GetAdaptersInfo(pAdapterInfo, &ulOutBufLen)) == NO_ERROR) { IP_ADAPTER_INFO *pAdapter = pAdapterInfo; while (pAdapter) { IP gateway = {0}, subnet_mask = {0}; if (addr_parse_ip(pAdapter->IpAddressList.IpMask.String, &subnet_mask) && addr_parse_ip(pAdapter->GatewayList.IpAddress.String, &gateway)) { if (gateway.family == TOX_AF_INET && subnet_mask.family == TOX_AF_INET) { IP_Port *ip_port = &ip_ports[count]; ip_port->ip.family = TOX_AF_INET; uint32_t gateway_ip = net_ntohl(gateway.ip.v4.uint32), subnet_ip = net_ntohl(subnet_mask.ip.v4.uint32); uint32_t broadcast_ip = gateway_ip + ~subnet_ip - 1; ip_port->ip.ip.v4.uint32 = net_htonl(broadcast_ip); ip_port->port = port; count++; if (count >= MAX_INTERFACES) { break; } } } pAdapter = pAdapter->Next; } } if (pAdapterInfo) { free(pAdapterInfo); } broadcast_count = count; for (uint32_t i = 0; i < count; i++) { broadcast_ip_ports[i] = ip_ports[i]; } }
/* Is IP a local ip or not. */ bool ip_is_local(IP ip) { if (ip.family == TOX_AF_INET) { IP4 ip4 = ip.ip.v4; /* Loopback. */ if (ip4.uint8[0] == 127) { return 1; } } else { /* embedded IPv4-in-IPv6 */ if (IPV6_IPV4_IN_V6(ip.ip.v6)) { IP ip4; ip4.family = TOX_AF_INET; ip4.ip.v4.uint32 = ip.ip.v6.uint32[3]; return ip_is_local(ip4); } /* localhost in IPv6 (::1) */ if (ip.ip.v6.uint64[0] == 0 && ip.ip.v6.uint32[2] == 0 && ip.ip.v6.uint32[3] == net_htonl(1)) { return 1; } } return 0; }
/* * Create a listening socket on bind_ip:port */ int net_bind( int *fd, const char *bind_ip, int port, int proto ) { #if defined(POLARSSL_HAVE_IPV6) int n, ret; struct addrinfo hints, *addr_list, *cur; char port_str[6]; if( ( ret = net_prepare() ) != 0 ) return( ret ); /* getaddrinfo expects port as a string */ memset( port_str, 0, sizeof( port_str ) ); polarssl_snprintf( port_str, sizeof( port_str ), "%d", port ); /* Bind to IPv6 and/or IPv4, but only in TCP */ memset( &hints, 0, sizeof( hints ) ); hints.ai_family = AF_UNSPEC; hints.ai_socktype = proto == NET_PROTO_UDP ? SOCK_DGRAM : SOCK_STREAM; hints.ai_protocol = proto == NET_PROTO_UDP ? IPPROTO_UDP : IPPROTO_TCP; if( bind_ip == NULL ) hints.ai_flags = AI_PASSIVE; if( getaddrinfo( bind_ip, port_str, &hints, &addr_list ) != 0 ) return( POLARSSL_ERR_NET_UNKNOWN_HOST ); /* Try the sockaddrs until a binding succeeds */ ret = POLARSSL_ERR_NET_UNKNOWN_HOST; for( cur = addr_list; cur != NULL; cur = cur->ai_next ) { *fd = (int) socket( cur->ai_family, cur->ai_socktype, cur->ai_protocol ); if( *fd < 0 ) { ret = POLARSSL_ERR_NET_SOCKET_FAILED; continue; } n = 1; if( setsockopt( *fd, SOL_SOCKET, SO_REUSEADDR, (const char *) &n, sizeof( n ) ) != 0 ) { close( *fd ); ret = POLARSSL_ERR_NET_SOCKET_FAILED; continue; } if( bind( *fd, cur->ai_addr, cur->ai_addrlen ) != 0 ) { close( *fd ); ret = POLARSSL_ERR_NET_BIND_FAILED; continue; } /* Listen only makes sense for TCP */ if( proto == NET_PROTO_TCP ) { if( listen( *fd, POLARSSL_NET_LISTEN_BACKLOG ) != 0 ) { close( *fd ); ret = POLARSSL_ERR_NET_LISTEN_FAILED; continue; } } /* I we ever get there, it's a success */ ret = 0; break; } freeaddrinfo( addr_list ); return( ret ); #else /* Legacy IPv4-only version */ int ret, n, c[4]; struct sockaddr_in server_addr; if( ( ret = net_prepare() ) != 0 ) return( ret ); if( ( *fd = (int) socket( AF_INET, proto == NET_PROTO_UDP ? SOCK_DGRAM : SOCK_STREAM, proto == NET_PROTO_UDP ? IPPROTO_UDP : IPPROTO_TCP ) ) < 0 ) return( POLARSSL_ERR_NET_SOCKET_FAILED ); n = 1; setsockopt( *fd, SOL_SOCKET, SO_REUSEADDR, (const char *) &n, sizeof( n ) ); server_addr.sin_addr.s_addr = net_htonl( INADDR_ANY ); server_addr.sin_family = AF_INET; server_addr.sin_port = net_htons( port ); if( bind_ip != NULL ) { memset( c, 0, sizeof( c ) ); sscanf( bind_ip, "%d.%d.%d.%d", &c[0], &c[1], &c[2], &c[3] ); for( n = 0; n < 4; n++ ) if( c[n] < 0 || c[n] > 255 ) break; if( n == 4 ) server_addr.sin_addr.s_addr = net_htonl( ( (uint32_t) c[0] << 24 ) | ( (uint32_t) c[1] << 16 ) | ( (uint32_t) c[2] << 8 ) | ( (uint32_t) c[3] ) ); } if( bind( *fd, (struct sockaddr *) &server_addr, sizeof( server_addr ) ) < 0 ) { close( *fd ); return( POLARSSL_ERR_NET_BIND_FAILED ); } /* Listen only makes sense for TCP */ if( proto == NET_PROTO_TCP ) { if( listen( *fd, POLARSSL_NET_LISTEN_BACKLOG ) != 0 ) { close( *fd ); return( POLARSSL_ERR_NET_LISTEN_FAILED ); } } return( 0 ); #endif /* POLARSSL_HAVE_IPV6 */ }