From 5d86252d01b43b40c9c34d5c12b731e85a8ffc1c Mon Sep 17 00:00:00 2001 From: midipix Date: Mar 22 2016 19:43:24 +0000 Subject: socket interfaces: sc_getpeername: initial integration. Integration of this function into the library has been delayed since the AFD ioctl operation, while succeeding, seems to only memset the caller's address buffer, and accordingly to never copy the remote socket address to it. Callers of sc_getpeername() should therefore first check the return value for success -- which may be used as indication that the socket is connected -- and then test the returned address buffer for validity. --- diff --git a/include/ntapi/nt_socket.h b/include/ntapi/nt_socket.h index fcf6d96..c984b92 100644 --- a/include/ntapi/nt_socket.h +++ b/include/ntapi/nt_socket.h @@ -413,6 +413,11 @@ typedef int32_t __cdecl ntapi_sc_getsockname( __in uint16_t * addrlen, __out nt_io_status_block * iosb __optional); +typedef int32_t __cdecl ntapi_sc_getpeername( + __in nt_socket * hssocket, + __in nt_sockaddr * addr, + __in uint16_t * addrlen, + __out nt_io_status_block * iosb __optional); typedef int32_t __cdecl ntapi_sc_server_accept_connection( __in nt_socket * hssocket, diff --git a/include/ntapi/ntapi.h b/include/ntapi/ntapi.h index d6e5f65..17d9871 100644 --- a/include/ntapi/ntapi.h +++ b/include/ntapi/ntapi.h @@ -544,6 +544,7 @@ typedef struct _ntapi_vtbl { ntapi_sc_recv * sc_recv; ntapi_sc_shutdown * sc_shutdown; ntapi_sc_getsockname * sc_getsockname; + ntapi_sc_getpeername * sc_getpeername; ntapi_sc_server_accept_connection * sc_server_accept_connection; ntapi_sc_server_duplicate_socket * sc_server_duplicate_socket; ntapi_sc_wait * sc_wait; diff --git a/project/common.mk b/project/common.mk index abbbb20..0e3bb9a 100644 --- a/project/common.mk +++ b/project/common.mk @@ -51,6 +51,8 @@ COMMON_SRCS = \ src/socket/ntapi_sc_bind_v2.c \ src/socket/ntapi_sc_connect_v1.c \ src/socket/ntapi_sc_connect_v2.c \ + src/socket/ntapi_sc_getpeername_v1.c \ + src/socket/ntapi_sc_getpeername_v2.c \ src/socket/ntapi_sc_getsockname_v1.c \ src/socket/ntapi_sc_getsockname_v2.c \ src/socket/ntapi_sc_listen.c \ diff --git a/src/internal/ntapi.c b/src/internal/ntapi.c index 048a8db..e8173ce 100644 --- a/src/internal/ntapi.c +++ b/src/internal/ntapi.c @@ -355,6 +355,7 @@ static int32_t __fastcall __ntapi_init_once(ntapi_vtbl ** pvtbl) __ntapi->sc_connect = __ntapi_sc_connect_v2; __ntapi->sc_server_accept_connection = __ntapi_sc_server_accept_connection_v2; __ntapi->sc_getsockname = __ntapi_sc_getsockname_v2; + __ntapi->sc_getpeername = __ntapi_sc_getpeername_v2; } else { __ntapi->tt_fork = __ntapi_tt_fork_v1; __ntapi->tt_create_native_process = __ntapi_tt_create_native_process_v1; @@ -364,6 +365,7 @@ static int32_t __fastcall __ntapi_init_once(ntapi_vtbl ** pvtbl) __ntapi->sc_connect = __ntapi_sc_connect_v1; __ntapi->sc_server_accept_connection = __ntapi_sc_server_accept_connection_v1; __ntapi->sc_getsockname = __ntapi_sc_getsockname_v1; + __ntapi->sc_getpeername = __ntapi_sc_getpeername_v1; } /* internals */ diff --git a/src/internal/ntapi_fnapi.h b/src/internal/ntapi_fnapi.h index 178f2ba..a22c659 100644 --- a/src/internal/ntapi_fnapi.h +++ b/src/internal/ntapi_fnapi.h @@ -198,6 +198,8 @@ ntapi_sc_connect __ntapi_sc_connect_v1; ntapi_sc_connect __ntapi_sc_connect_v2; ntapi_sc_getsockname __ntapi_sc_getsockname_v1; ntapi_sc_getsockname __ntapi_sc_getsockname_v2; +ntapi_sc_getpeername __ntapi_sc_getpeername_v1; +ntapi_sc_getpeername __ntapi_sc_getpeername_v2; ntapi_sc_server_accept_connection __ntapi_sc_server_accept_connection_v1; ntapi_sc_server_accept_connection __ntapi_sc_server_accept_connection_v2; ntapi_sc_server_duplicate_socket __ntapi_sc_server_duplicate_socket; diff --git a/src/socket/ntapi_sc_getpeername_v1.c b/src/socket/ntapi_sc_getpeername_v1.c new file mode 100644 index 0000000..f38e11a --- /dev/null +++ b/src/socket/ntapi_sc_getpeername_v1.c @@ -0,0 +1,80 @@ +/********************************************************/ +/* ntapi: Native API core library */ +/* Copyright (C) 2013--2016 Z. Gilboa */ +/* Released under GPLv2 and GPLv3; see COPYING.NTAPI. */ +/********************************************************/ + +#include +#include +#include +#include +#include +#include "ntapi_impl.h" + +typedef struct _nt_afd_server_socket_name_info { + uint32_t unknown; + uint32_t type; + uint32_t service_flags; + char sa_data[14]; +} nt_afd_server_socket_name_info; + + +struct __addr_memcpy { + uint16_t d0; + uint16_t d1; + uint16_t d2; + uint16_t d3; + uint16_t d4; + uint16_t d5; + uint16_t d6; + uint16_t d7; +}; + + +int32_t __cdecl __ntapi_sc_getpeername_v1( + __in nt_socket * hssocket, + __in nt_sockaddr * addr, + __in uint16_t * addrlen, + __out nt_io_status_block * iosb __optional) +{ + nt_io_status_block siosb; + nt_afd_server_socket_name_info sock_name_info; + + struct __addr_memcpy * asrc; + struct __addr_memcpy * adst; + + iosb = iosb ? iosb : &siosb; + + hssocket->iostatus = __ntapi->zw_device_io_control_file( + hssocket->hsocket, + hssocket->hevent, + 0, + 0, + iosb, + NT_AFD_IOCTL_GET_PEER_NAME, + 0, + 0, + &sock_name_info, + sizeof(sock_name_info)); + + __ntapi->sc_wait(hssocket,iosb,0); + + if (!hssocket->iostatus) { + addr->sa_addr_in4.sa_family = hssocket->domain; + + asrc = (struct __addr_memcpy *)&(sock_name_info.sa_data); + adst = (struct __addr_memcpy *)addr; + + adst->d1 = asrc->d0; + adst->d2 = asrc->d1; + adst->d3 = asrc->d2; + adst->d4 = asrc->d3; + adst->d5 = asrc->d4; + adst->d6 = asrc->d5; + adst->d7 = asrc->d6; + + *addrlen = (uint16_t)iosb->info; + }; + + return hssocket->iostatus; +} diff --git a/src/socket/ntapi_sc_getpeername_v2.c b/src/socket/ntapi_sc_getpeername_v2.c new file mode 100644 index 0000000..58c3662 --- /dev/null +++ b/src/socket/ntapi_sc_getpeername_v2.c @@ -0,0 +1,42 @@ +/********************************************************/ +/* ntapi: Native API core library */ +/* Copyright (C) 2013--2016 Z. Gilboa */ +/* Released under GPLv2 and GPLv3; see COPYING.NTAPI. */ +/********************************************************/ + +#include +#include +#include +#include +#include +#include "ntapi_impl.h" + +int32_t __cdecl __ntapi_sc_getpeername_v2( + __in nt_socket * hssocket, + __in nt_sockaddr * addr, + __in uint16_t * addrlen, + __out nt_io_status_block * iosb __optional) +{ + nt_iosb siosb; + + iosb = iosb ? iosb : &siosb; + + hssocket->iostatus = __ntapi->zw_device_io_control_file( + hssocket->hsocket, + hssocket->hevent, + 0, + 0, + iosb, + NT_AFD_IOCTL_GET_PEER_NAME, + 0, + 0, + addr, + sizeof(*addr)); + + __ntapi->sc_wait(hssocket,iosb,0); + + if (!hssocket->iostatus) + *addrlen = (uint16_t)iosb->info; + + return hssocket->iostatus; +}