Example #1
0
/*
 * Write at most 'len' characters
 */
int mbedtls_mediatek_send( void *ctx, const unsigned char *buf, size_t len )
{
    int ret;
    int fd = ((mbedtls_net_context *) ctx)->fd;

    if( fd < 0 )
        return( MBEDTLS_ERR_NET_INVALID_CONTEXT );

    ret = (int) vm_send(fd, buf, len, 0);
    
    if( ret < 0 )
    {
        if( net_would_block( ctx ) != 0 )
            return( MBEDTLS_ERR_SSL_WANT_WRITE );

#if ( defined(_WIN32) || defined(_WIN32_WCE) ) && !defined(EFIX64) && \
    !defined(EFI32)
        if( WSAGetLastError() == WSAECONNRESET )
            return( MBEDTLS_ERR_NET_CONN_RESET );
#else
        if( errno == EPIPE || errno == ECONNRESET )
            return( MBEDTLS_ERR_NET_CONN_RESET );

        if( errno == EINTR )
            return( MBEDTLS_ERR_SSL_WANT_WRITE );
#endif

        return( MBEDTLS_ERR_NET_SEND_FAILED );
    }

    return( ret );
}
Example #2
0
/*
 * Write at most 'len' characters
 */
int mbedtls_net_send( void *ctx, const unsigned char *buf, size_t len )
{
    int ret;
    int fd = ((mbedtls_net_context *) ctx)->fd;

    int error = 0;

    if ( fd < 0 ) {
        return ( MBEDTLS_ERR_NET_INVALID_CONTEXT );
    }

    ret = (int) write( fd, buf, len );

    if ( ret < 0 ) {
        if ( net_would_block( ctx, &error ) != 0 ) {
            return ( MBEDTLS_ERR_SSL_WANT_WRITE );
        }

        if ( error == EPIPE || error == ECONNRESET ) {
            return ( MBEDTLS_ERR_NET_CONN_RESET );
        }

        if ( error == EINTR ) {
            return ( MBEDTLS_ERR_SSL_WANT_WRITE );
        }

        return ( MBEDTLS_ERR_NET_SEND_FAILED );
    }

    return ( ret );
}
Example #3
0
/*
 * Write at most 'len' characters
 */
int net_send( void *ctx, const unsigned char *buf, size_t len )
{
    int fd = *((int *) ctx);
    int ret = (int) write( fd, buf, len );

    if( ret < 0 )
    {
        if( net_would_block( fd ) != 0 )
            return( POLARSSL_ERR_NET_WANT_WRITE );

#if ( defined(_WIN32) || defined(_WIN32_WCE) ) && !defined(EFIX64) && \
    !defined(EFI32)
        if( WSAGetLastError() == WSAECONNRESET )
            return( POLARSSL_ERR_NET_CONN_RESET );
#else
        if( errno == EPIPE || errno == ECONNRESET )
            return( POLARSSL_ERR_NET_CONN_RESET );

        if( errno == EINTR )
            return( POLARSSL_ERR_NET_WANT_WRITE );
#endif

        return( POLARSSL_ERR_NET_SEND_FAILED );
    }

    return( ret );
}
Example #4
0
/*
 * Read at most 'len' characters
 */
int net_recv( void *ctx, unsigned char *buf, size_t len )
{
    int fd = *((int *) ctx);
    int ret = read( fd, buf, len );

    if( ret < 0 )
    {
        if( net_would_block( fd ) != 0 )
            return( POLARSSL_ERR_NET_WANT_READ );

#if ( defined(_WIN32) || defined(_WIN32_WCE) ) && !defined(EFIX64) && \
    !defined(EFI32)
        if( WSAGetLastError() == WSAECONNRESET )
            return( POLARSSL_ERR_NET_CONN_RESET );
#else
#ifdef ERRNO
        if( errno == EPIPE || errno == ECONNRESET )
            return( POLARSSL_ERR_NET_CONN_RESET );

        if( errno == EINTR )
            return( POLARSSL_ERR_NET_WANT_READ );
#endif
#endif

        return( POLARSSL_ERR_NET_RECV_FAILED );
    }

    return( ret );
}
Example #5
0
/*
 * Read at most 'len' characters and write to buf.
 */
static int recv_custom( void *ctx, unsigned char *buf, size_t len )
{
    int ret;
#if SOCKET_COMMUNICATION
    int fd = *((int *) ctx);

    if( fd < 0 )
        return( POLARSSL_ERR_NET_SOCKET_FAILED );
    ret = (int) read( fd, buf, len );
#else
    ((void) ctx);
    ((void) len);

    if ( ((*recv_off + len) <= BUF_SIZE) && memcpy( buf, &shared_buf[*recv_off], len ) )
    {
        *recv_off += len;
        if( *recv_off == *send_off )
        {
            /*
             * Done copying buffer.
             * Reset offsets for next calls of send and rcv functions.
             */
            *recv_off = 0;
            *send_off = 0;
        }
        /* Imitate the return value of read(2). */
        ret = len;
    }
    else
    {
        ret = -1;
    }
#endif

#if SOCKET_COMMUNICATION
    if( ret < 0 )
    {
        if( net_would_block( fd ) != 0 )
            return( POLARSSL_ERR_NET_WANT_READ );

#if ( defined(_WIN32) || defined(_WIN32_WCE) ) && !defined(EFIX64) && \
    !defined(EFI32)
        if( WSAGetLastError() == WSAECONNRESET )
            return( POLARSSL_ERR_NET_CONN_RESET );
#else
        if( errno == EPIPE || errno == ECONNRESET )
            return( POLARSSL_ERR_NET_CONN_RESET );

        if( errno == EINTR )
            return( POLARSSL_ERR_NET_WANT_READ );
#endif

        return( POLARSSL_ERR_NET_RECV_FAILED );
    }
#endif

    return( ret );
}
Example #6
0
/*
 * Accept a connection from a remote client
 */
int net_accept( int bind_fd, int *client_fd, void *client_ip )
{
#if defined(POLARSSL_HAVE_IPV6)
    struct sockaddr_storage client_addr;
#else
    struct sockaddr_in client_addr;
#endif

#if defined(__socklen_t_defined) || defined(_SOCKLEN_T) ||  \
    defined(_SOCKLEN_T_DECLARED)
    socklen_t n = (socklen_t) sizeof( client_addr );
#else
    int n = (int) sizeof( client_addr );
#endif

    *client_fd = (int) accept( bind_fd, (struct sockaddr *)
                               &client_addr, &n );

    if( *client_fd < 0 )
    {
        if( net_would_block( *client_fd ) != 0 )
            return( POLARSSL_ERR_NET_WANT_READ );

        return( POLARSSL_ERR_NET_ACCEPT_FAILED );
    }

    if( client_ip != NULL )
    {
#if defined(POLARSSL_HAVE_IPV6)
        if( client_addr.ss_family == AF_INET )
        {
            struct sockaddr_in *addr4 = (struct sockaddr_in *) &client_addr;
            memcpy( client_ip, &addr4->sin_addr.s_addr,
                        sizeof( addr4->sin_addr.s_addr ) );
        }
        else
        {
            struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *) &client_addr;
            memcpy( client_ip, &addr6->sin6_addr.s6_addr,
                        sizeof( addr6->sin6_addr.s6_addr ) );
        }
#else
        memcpy( client_ip, &client_addr.sin_addr.s_addr,
                    sizeof( client_addr.sin_addr.s_addr ) );
#endif /* POLARSSL_HAVE_IPV6 */
    }

    return( 0 );
}
int CConsoleNetConnection::Update()
{
	if(State() == NET_CONNSTATE_ONLINE)
	{
		if((int)(sizeof(m_aBuffer)) <= m_BufferOffset)
		{
			m_State = NET_CONNSTATE_ERROR;
			str_copy(m_aErrorString, "too weak connection (out of buffer)", sizeof(m_aErrorString));
			return -1;
		}

		int Bytes = net_tcp_recv(m_Socket, m_aBuffer+m_BufferOffset, (int)(sizeof(m_aBuffer))-m_BufferOffset);

		if(Bytes > 0)
		{
			m_BufferOffset += Bytes;
		}
		else if(Bytes < 0)
		{
			if(net_would_block()) // no data received
				return 0;

			m_State = NET_CONNSTATE_ERROR; // error
			str_copy(m_aErrorString, "connection failure", sizeof(m_aErrorString));
			return -1;
		}
		else
		{
			m_State = NET_CONNSTATE_ERROR;
			str_copy(m_aErrorString, "remote end closed the connection", sizeof(m_aErrorString));
			return -1;
		}
	}

	return 0;
}
Example #8
0
/*
 * Write at most 'len' characters to shared buffer or file.
 * Multiple sends can occur before a receive; therefore, maintain an
 * offset.
 * Also, write content of file to shared buffer, if desired (determined
 * by command-line options).
 */
static int send_custom( void *ctx, const unsigned char *buf,
                        size_t len )
{
    int ret;
#if SOCKET_COMMUNICATION
    int fd = *((int *) ctx);

    if( fd < 0 )
        return( POLARSSL_ERR_NET_SOCKET_FAILED );
#else
    ((void) ctx);
#endif

    /* Read packet from file or write packet to file */
    if( packet_count == packet_in_num )
    {
        FILE *in_file;
#if !SOCKET_COMMUNICATION
        size_t rlen;
#endif

        if( !packet_in_file )
        {
            polarssl_fprintf( stderr, "Packet input file not specified!\n" );
            exit(1);
        }

        /* Read packet from file, ignoring buf */
        in_file = fopen( packet_in_file, "rb" );

        if( !in_file )
        {
            perror( "Unable to open packet input file" );
            exit( 1 );
        }

        /* Write packet to socket/buffer. */
#if SOCKET_COMMUNICATION
        ret = (int) write( fd, buf, len );
#else
        rlen = fread( shared_buf, sizeof(shared_buf[0]), BUF_SIZE,
                      in_file );
#endif
        if ( ferror( in_file ) )
        {
            perror( "Unable to read packet input file" );
            exit( 1 );
        }
#if !SOCKET_COMMUNICATION
        else {
            *send_off += rlen;
            ret = rlen;
        }
#endif
        fclose( in_file );
    }
    else
    {
        /* Write packet to socket/buffer. */
#if SOCKET_COMMUNICATION
        ret = (int) write( fd, buf, len );
#else
        if ( (len <= BUF_SIZE) && memcpy( shared_buf, buf, len ) )
        {
            *send_off += len;
            ret = len;
        }
        else
        {
            ret = -1;
        }
#endif

        if( packet_in_num == 0 )
        {
            char out_filename[100];
            FILE *out_file;

            /* Write packet to file. */
            snprintf( out_filename, sizeof(out_filename), "%s%zd",
                      PACKET_FILE_PREFIX, packet_count );
            out_file = fopen( out_filename, "wb" );
            fwrite( buf, sizeof(char), len, out_file );
            fclose( out_file );
        }
    }
    packet_count++;

#if SOCKET_COMMUNICATION
    if( ret < 0 )
    {
        if( net_would_block( fd ) != 0 )
            return( POLARSSL_ERR_NET_WANT_WRITE );

#if(  defined(_WIN32) || defined(_WIN32_WCE) ) && !defined(EFIX64) && \
    !defined(EFI32)
        if( WSAGetLastError() == WSAECONNRESET )
            return( POLARSSL_ERR_NET_CONN_RESET );
#else
        if( errno == EPIPE || errno == ECONNRESET )
            return( POLARSSL_ERR_NET_CONN_RESET );

        if( errno == EINTR )
            return( POLARSSL_ERR_NET_WANT_WRITE );
#endif

        return( POLARSSL_ERR_NET_SEND_FAILED );
    }
#endif

    return( ret );
}
Example #9
0
/*
 * Accept a connection from a remote client
 */
int mbedtls_net_accept( mbedtls_net_context *bind_ctx,
                        mbedtls_net_context *client_ctx,
                        void *client_ip, size_t buf_size, size_t *ip_len )
{
    int ret;
    int type;

    struct sockaddr_storage client_addr;

#if defined(__socklen_t_defined) || defined(_SOCKLEN_T) ||  \
    defined(_SOCKLEN_T_DECLARED) || defined(__DEFINED_socklen_t)
    socklen_t n = (socklen_t) sizeof( client_addr );
    socklen_t type_len = (socklen_t) sizeof( type );
#else
    int n = (int) sizeof( client_addr );
    int type_len = (int) sizeof( type );
#endif

    /* Is this a TCP or UDP socket? */
    if( getsockopt( bind_ctx->fd, SOL_SOCKET, SO_TYPE,
                    (void *) &type, &type_len ) != 0 ||
            ( type != SOCK_STREAM && type != SOCK_DGRAM ) )
    {
        return( MBEDTLS_ERR_NET_ACCEPT_FAILED );
    }

    if( type == SOCK_STREAM )
    {
        /* TCP: actual accept() */
        ret = client_ctx->fd = (int) accept( bind_ctx->fd,
                                             (struct sockaddr *) &client_addr, &n );
    }
    else
    {
        /* UDP: wait for a message, but keep it in the queue */
        char buf[1] = { 0 };

        ret = (int) recvfrom( bind_ctx->fd, buf, sizeof( buf ), MSG_PEEK,
                              (struct sockaddr *) &client_addr, &n );

#if defined(_WIN32)
        if( ret == SOCKET_ERROR &&
                WSAGetLastError() == WSAEMSGSIZE )
        {
            /* We know buf is too small, thanks, just peeking here */
            ret = 0;
        }
#endif
    }

    if( ret < 0 )
    {
        if( net_would_block( bind_ctx ) != 0 )
            return( MBEDTLS_ERR_SSL_WANT_READ );

        return( MBEDTLS_ERR_NET_ACCEPT_FAILED );
    }

    /* UDP: hijack the listening socket to communicate with the client,
     * then bind a new socket to accept new connections */
    if( type != SOCK_STREAM )
    {
        struct sockaddr_storage local_addr;
        int one = 1;

        if( connect( bind_ctx->fd, (struct sockaddr *) &client_addr, n ) != 0 )
            return( MBEDTLS_ERR_NET_ACCEPT_FAILED );

        client_ctx->fd = bind_ctx->fd;
        bind_ctx->fd   = -1; /* In case we exit early */

        n = sizeof( struct sockaddr_storage );
        if( getsockname( client_ctx->fd,
                         (struct sockaddr *) &local_addr, &n ) != 0 ||
                ( bind_ctx->fd = (int) socket( local_addr.ss_family,
                                               SOCK_DGRAM, IPPROTO_UDP ) ) < 0 ||
                setsockopt( bind_ctx->fd, SOL_SOCKET, SO_REUSEADDR,
                            (const char *) &one, sizeof( one ) ) != 0 )
        {
            return( MBEDTLS_ERR_NET_SOCKET_FAILED );
        }

        if( bind( bind_ctx->fd, (struct sockaddr *) &local_addr, n ) != 0 )
        {
            return( MBEDTLS_ERR_NET_BIND_FAILED );
        }
    }

    if( client_ip != NULL )
    {
        if( client_addr.ss_family == AF_INET )
        {
            struct sockaddr_in *addr4 = (struct sockaddr_in *) &client_addr;
            *ip_len = sizeof( addr4->sin_addr.s_addr );

            if( buf_size < *ip_len )
                return( MBEDTLS_ERR_NET_BUFFER_TOO_SMALL );

            memcpy( client_ip, &addr4->sin_addr.s_addr, *ip_len );
        }
        else
        {
            struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *) &client_addr;
            *ip_len = sizeof( addr6->sin6_addr.s6_addr );

            if( buf_size < *ip_len )
                return( MBEDTLS_ERR_NET_BUFFER_TOO_SMALL );

            memcpy( client_ip, &addr6->sin6_addr.s6_addr, *ip_len);
        }
    }

    return( 0 );
}
Example #10
0
/*
 * Accept a connection from a remote client
 */
int net_accept( int bind_fd, int *client_fd, void *client_ip )
{
    int ret;
    int type;

#if defined(POLARSSL_HAVE_IPV6)
    struct sockaddr_storage client_addr;
#else
    struct sockaddr_in client_addr;
#endif

#if defined(__socklen_t_defined) || defined(_SOCKLEN_T) ||  \
    defined(_SOCKLEN_T_DECLARED)
    socklen_t n = (socklen_t) sizeof( client_addr );
    socklen_t type_len = (socklen_t) sizeof( type );
#else
    int n = (int) sizeof( client_addr );
    int type_len = (int) sizeof( type );
#endif

    /* Is this a TCP or UDP socket? */
    if( getsockopt( bind_fd, SOL_SOCKET, SO_TYPE, &type, &type_len ) != 0 ||
        ( type != SOCK_STREAM && type != SOCK_DGRAM ) )
    {
        return( POLARSSL_ERR_NET_ACCEPT_FAILED );
    }

    if( type == SOCK_STREAM )
    {
        /* TCP: actual accept() */
        ret = *client_fd = (int) accept( bind_fd,
                                         (struct sockaddr *) &client_addr, &n );
    }
    else
    {
        /* UDP: wait for a message, but keep it in the queue */
        char buf[1] = { 0 };

        ret = recvfrom( bind_fd, buf, sizeof( buf ), MSG_PEEK,
                        (struct sockaddr *) &client_addr, &n );
    }

    if( ret < 0 )
    {
        if( net_would_block( bind_fd ) != 0 )
            return( POLARSSL_ERR_NET_WANT_READ );

        return( POLARSSL_ERR_NET_ACCEPT_FAILED );
    }

    /* UDP: hijack the listening socket for communicating with the client */
    if( type != SOCK_STREAM )
    {
        if( connect( bind_fd, (struct sockaddr *) &client_addr, n ) != 0 )
            return( POLARSSL_ERR_NET_ACCEPT_FAILED );

        *client_fd = bind_fd;
    }

    if( client_ip != NULL )
    {
#if defined(POLARSSL_HAVE_IPV6)
        if( client_addr.ss_family == AF_INET )
        {
            struct sockaddr_in *addr4 = (struct sockaddr_in *) &client_addr;
            memcpy( client_ip, &addr4->sin_addr.s_addr,
                        sizeof( addr4->sin_addr.s_addr ) );
        }
        else
        {
            struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *) &client_addr;
            memcpy( client_ip, &addr6->sin6_addr.s6_addr,
                        sizeof( addr6->sin6_addr.s6_addr ) );
        }
#else
        memcpy( client_ip, &client_addr.sin_addr.s_addr,
                    sizeof( client_addr.sin_addr.s_addr ) );
#endif /* POLARSSL_HAVE_IPV6 */
    }

    return( 0 );
}
Example #11
0
/*
 * Read at most 'len' characters, blocking for at most 'timeout' ms
 */
int mbedtls_net_recv_timeout( void *ctx, unsigned char *buf, size_t len,
                      uint32_t timeout )
{
    int ret;
    struct timeval tv;
    fd_set read_fds;
    int fd = ((mbedtls_net_context *) ctx)->fd;

    if( fd < 0 )
        return( MBEDTLS_ERR_NET_INVALID_CONTEXT );

    FD_ZERO( &read_fds );
    FD_SET( fd, &read_fds );

    tv.tv_sec  = timeout / 1000;
    tv.tv_usec = ( timeout % 1000 ) * 1000;

#if defined(__CELLOS_LV2__)
    ret = socketselect(fd + 1, &read_fds, NULL, NULL, timeout == 0 ? NULL : &tv);
#elif defined(VITA)
   extern int retro_epoll_fd;
   SceNetEpollEvent ev = {0};

   ev.events = SCE_NET_EPOLLIN | SCE_NET_EPOLLHUP;
   ev.data.fd = fd + 1;

   if((sceNetEpollControl(retro_epoll_fd, SCE_NET_EPOLL_CTL_ADD, fd + 1, &ev)))
   {
      int ret = sceNetEpollWait(retro_epoll_fd, &ev, 1, 0);
      sceNetEpollControl(retro_epoll_fd, SCE_NET_EPOLL_CTL_DEL, fd + 1, NULL);
#else
    ret = select( fd + 1, &read_fds, NULL, NULL, timeout == 0 ? NULL : &tv );
#endif
    /* Zero fds ready means we timed out */
    if( ret == 0 )
        return( MBEDTLS_ERR_SSL_TIMEOUT );

    if( ret < 0 )
    {
#if ( defined(_WIN32) || defined(_WIN32_WCE) ) && !defined(EFIX64) && \
    !defined(EFI32)
        if( WSAGetLastError() == WSAEINTR )
            return( MBEDTLS_ERR_SSL_WANT_READ );
#else
        if( errno == EINTR )
            return( MBEDTLS_ERR_SSL_WANT_READ );
#endif

        return( MBEDTLS_ERR_NET_RECV_FAILED );
    }

    /* This call will not block */
    return( mbedtls_net_recv( ctx, buf, len ) );
}

/*
 * Write at most 'len' characters
 */
int mbedtls_net_send( void *ctx, const unsigned char *buf, size_t len )
{
    int ret;
    int fd = ((mbedtls_net_context *) ctx)->fd;

    if( fd < 0 )
        return( MBEDTLS_ERR_NET_INVALID_CONTEXT );

    ret = (int) write( fd, buf, len );

    if( ret < 0 )
    {
        if( net_would_block( ctx ) != 0 )
            return( MBEDTLS_ERR_SSL_WANT_WRITE );

#if ( defined(_WIN32) || defined(_WIN32_WCE) ) && !defined(EFIX64) && \
    !defined(EFI32)
        if( WSAGetLastError() == WSAECONNRESET )
            return( MBEDTLS_ERR_NET_CONN_RESET );
#else
        if( errno == EPIPE || errno == ECONNRESET )
            return( MBEDTLS_ERR_NET_CONN_RESET );

        if( errno == EINTR )
            return( MBEDTLS_ERR_SSL_WANT_WRITE );
#endif

        return( MBEDTLS_ERR_NET_SEND_FAILED );
    }

    return( ret );
}
Example #12
0
/*
 * Accept a connection from a remote client
 */
int mbedtls_net_accept( mbedtls_net_context *bind_ctx,
                        mbedtls_net_context *client_ctx,
                        void *client_ip, size_t buf_size, size_t *ip_len )
{
    int ret;
    int type;

    struct sockaddr_in client_addr;

    socklen_t n = (socklen_t) sizeof( client_addr );
    socklen_t type_len = (socklen_t) sizeof( type );

    /* Is this a TCP or UDP socket? */
    if ( getsockopt( bind_ctx->fd, SOL_SOCKET, SO_TYPE,
                     (void *) &type, (socklen_t *) &type_len ) != 0 ||
            ( type != SOCK_STREAM && type != SOCK_DGRAM ) ) {
        return ( MBEDTLS_ERR_NET_ACCEPT_FAILED );
    }

    if ( type == SOCK_STREAM ) {
        /* TCP: actual accept() */
        ret = client_ctx->fd = (int) accept( bind_ctx->fd,
                                             (struct sockaddr *) &client_addr, &n );
    } else {
        /* UDP: wait for a message, but keep it in the queue */
        char buf[1] = { 0 };

        ret = recvfrom( bind_ctx->fd, buf, sizeof( buf ), MSG_PEEK,
                        (struct sockaddr *) &client_addr, &n );

    }

    if ( ret < 0 ) {
        if ( net_would_block( bind_ctx, NULL ) != 0 ) {
            return ( MBEDTLS_ERR_SSL_WANT_READ );
        }

        return ( MBEDTLS_ERR_NET_ACCEPT_FAILED );
    }

    /* UDP: hijack the listening socket to communicate with the client,
     * then bind a new socket to accept new connections */
    if ( type != SOCK_STREAM ) {
        struct sockaddr_in local_addr;
        int one = 1;

        if ( connect( bind_ctx->fd, (struct sockaddr *) &client_addr, n ) != 0 ) {
            return ( MBEDTLS_ERR_NET_ACCEPT_FAILED );
        }

        client_ctx->fd = bind_ctx->fd;
        bind_ctx->fd   = -1; /* In case we exit early */

        n = sizeof( struct sockaddr_in );
        if ( getsockname( client_ctx->fd,
                          (struct sockaddr *) &local_addr, &n ) != 0 ||
                ( bind_ctx->fd = (int) socket( AF_INET,
                                               SOCK_DGRAM, IPPROTO_UDP ) ) < 0 ||
                setsockopt( bind_ctx->fd, SOL_SOCKET, SO_REUSEADDR,
                            (const char *) &one, sizeof( one ) ) != 0 ) {
            return ( MBEDTLS_ERR_NET_SOCKET_FAILED );
        }

        if ( bind( bind_ctx->fd, (struct sockaddr *) &local_addr, n ) != 0 ) {
            return ( MBEDTLS_ERR_NET_BIND_FAILED );
        }
    }

    if ( client_ip != NULL ) {
        struct sockaddr_in *addr4 = (struct sockaddr_in *) &client_addr;
        *ip_len = sizeof( addr4->sin_addr.s_addr );

        if ( buf_size < *ip_len ) {
            return ( MBEDTLS_ERR_NET_BUFFER_TOO_SMALL );
        }

        memcpy( client_ip, &addr4->sin_addr.s_addr, *ip_len );
    }

    return ( 0 );
}