55#include <winsock2.h>
66#include <ws2tcpip.h>
77
8- DWORD resolve_host (LPCSTR hostname , u_short ai_family , struct in_addr * result , struct in6_addr * result6 )
8+ /// <summary>
9+ /// Resolve a hostname. Don't forget to call `freeaddrinfo` on the `out` parameter once done with it.
10+ /// </summary>
11+ /// <param name="hostname">Long pointer to a string</param>
12+ /// <param name="ai_family">The family to get the IP address for (IPv6 / IPv4)</param>
13+ /// <param name="out">The resulting addrinfo structure</param>
14+ /// <returns>0 on success, a Windows error code on error</returns>
15+ DWORD resolve_host (const LPCSTR hostname , u_short ai_family , struct addrinfo * * out )
916{
10- struct addrinfo hints , * list ;
11- struct in_addr addr ;
12- struct in6_addr addr6 ;
13- struct sockaddr_in * sockaddr_ipv4 ;
14- struct sockaddr_in6 * sockaddr_ipv6 ;
15- int iResult ;
17+ if (hostname == NULL )
18+ {
19+ dprintf ("Hostname not set" );
20+ return ERROR_INVALID_PARAMETER ;
21+ }
22+
23+ if (out == NULL )
24+ {
25+ dprintf ("Null pointer provided as output to resolve_host" );
26+ return ERROR_INVALID_PARAMETER ;
27+ }
1628
1729 WSADATA wsaData ;
18- iResult = WSAStartup (MAKEWORD (2 ,2 ), & wsaData );
19- if (iResult != NO_ERROR )
30+ DWORD iResult = WSAStartup (MAKEWORD (2 , 2 ), & wsaData );
31+ if (iResult != ERROR_SUCCESS )
2032 {
2133 dprintf ("Could not initialise Winsock: %x." , iResult );
2234 return iResult ;
2335 }
2436
25- memset ( & hints , 0 , sizeof ( hints )) ;
37+ struct addrinfo hints = { 0 } ;
2638 hints .ai_socktype = SOCK_DGRAM ;
2739 hints .ai_protocol = IPPROTO_UDP ;
2840 hints .ai_family = ai_family ;
2941
3042 dprintf ("Attempting to resolve '%s'" , hostname );
3143
32- iResult = getaddrinfo (hostname , NULL , & hints , & list );
33-
34- if (iResult != NO_ERROR )
44+ iResult = getaddrinfo (hostname , NULL , & hints , out );
45+ if (iResult != ERROR_SUCCESS )
3546 {
36- dprintf ("Unable to resolve host Error: %x." , iResult );
47+ dprintf ("Unable to resolve host '%s' Error: %x." , hostname , iResult );
3748 dprintf ("Error msg: %s" , gai_strerror (iResult ));
49+ return iResult ;
50+ }
51+ dprintf ("Resolved host '%s' successfully" , hostname );
52+
53+ dprintf ("Performing Win Socket cleanup" );
54+ iResult = WSACleanup ();
55+ if (iResult != ERROR_SUCCESS )
56+ {
57+ dprintf ("WSACleanup failed with return code %x" , iResult );
58+ return iResult ;
3859 }
39- else
60+ dprintf ("WSACleanup completed successfully" );
61+
62+ return ERROR_SUCCESS ;
63+ }
64+
65+ /// <summary>
66+ /// Add in all resolved IP addresses for a specific hostname to a TLV group.
67+ /// </summary>
68+ /// <param name="group">The group to insert resolved host IP addresses into.</param>
69+ /// <param name="host">The hostname to resolve</param>
70+ /// <returns>0 on success.</returns>
71+ DWORD add_all_host_ips_to_group (Packet * * group , struct addrinfo * host )
72+ {
73+ for (struct addrinfo * current = host ; current != NULL ; current = current -> ai_next )
4074 {
41- switch (list -> ai_family ) {
75+ switch (current -> ai_family )
76+ {
4277 case AF_INET :
43- sockaddr_ipv4 = (struct sockaddr_in * ) list -> ai_addr ;
44- addr = sockaddr_ipv4 -> sin_addr ;
45- memcpy ((void * )result , & addr , sizeof (result ));
78+ dprintf ("Adding IP v4 Family to Group TLV" );
79+ met_api -> packet .add_tlv_uint (* group , TLV_TYPE_ADDR_TYPE , (UINT )current -> ai_family );
80+ dprintf ("Adding IP v4 Address to Group TLV" );
81+ struct in_addr ipv4_addr = ((struct sockaddr_in * )(current -> ai_addr ))-> sin_addr ;
82+ met_api -> packet .add_tlv_raw (* group , TLV_TYPE_IP , & ipv4_addr , sizeof (struct in_addr ));
83+ break ;
4684 case AF_INET6 :
47- sockaddr_ipv6 = (struct sockaddr_in6 * ) list -> ai_addr ;
48- addr6 = sockaddr_ipv6 -> sin6_addr ;
49- memcpy ((void * )result6 , & addr6 , sizeof (struct in6_addr ));
50- default :
85+ dprintf ("Adding IP v6 Family to Group TLV" );
86+ met_api -> packet .add_tlv_uint (* group , TLV_TYPE_ADDR_TYPE , (UINT )current -> ai_family );
87+ dprintf ("Adding IP v6 Address to Group TLV" );
88+ struct in6_addr ipv6_addr = ((struct sockaddr_in6 * )(current -> ai_addr ))-> sin6_addr ;
89+ met_api -> packet .add_tlv_raw (* group , TLV_TYPE_IP , & ipv6_addr , sizeof (struct in6_addr ));
5190 break ;
91+ default :
92+ dprintf ("Unknown family, skipping entry." );
93+ continue ;
5294 }
5395 }
54-
55- freeaddrinfo (list );
56- WSACleanup ();
57-
58- return iResult ;
96+ return ERROR_SUCCESS ;
5997}
6098
6199DWORD request_resolve_host (Remote * remote , Packet * packet )
62100{
63101 Packet * response = met_api -> packet .create_response (packet );
64- LPCSTR hostname = NULL ;
65- struct in_addr addr ;
66- struct in6_addr addr6 ;
67- u_short ai_family = AF_INET ;
68- int iResult ;
102+ LPCSTR hostname = met_api -> packet .get_tlv_value_string (packet , TLV_TYPE_HOST_NAME );
103+ u_short ai_family = met_api -> packet .get_tlv_value_uint (packet , TLV_TYPE_ADDR_TYPE );
104+ DWORD iResult = ERROR_SUCCESS ;
69105
70- hostname = met_api -> packet .get_tlv_value_string (packet , TLV_TYPE_HOST_NAME );
106+ struct addrinfo * result = NULL ;
107+ iResult = resolve_host (hostname , ai_family , & result );
108+ if (iResult != ERROR_SUCCESS || result == NULL )
109+ {
110+ dprintf ("Could not resolve_host for '%s': %x" , hostname , iResult );
111+ goto done ;
112+ }
71113
72- if (!hostname )
114+ dprintf ("Creating group for resolve host entry" );
115+ Packet * resolved_hosts = met_api -> packet .create_group ();
116+ if (resolved_hosts == NULL )
73117 {
74- iResult = ERROR_INVALID_PARAMETER ;
75- dprintf ( "Hostname not set" ) ;
118+ dprintf ( "Could not create TLV Group" ) ;
119+ goto done ;
76120 }
77- else
121+
122+ DWORD adding_host_ips = add_all_host_ips_to_group (& resolved_hosts , result );
123+ if (adding_host_ips != ERROR_SUCCESS )
78124 {
79- ai_family = met_api -> packet .get_tlv_value_uint (packet , TLV_TYPE_ADDR_TYPE );
80- iResult = resolve_host (hostname , ai_family , & addr , & addr6 );
81- if (iResult == NO_ERROR )
82- {
83- if (ai_family == AF_INET )
84- {
85- met_api -> packet .add_tlv_raw (response , TLV_TYPE_IP , & addr , sizeof (struct in_addr ));
86- } else {
87- met_api -> packet .add_tlv_raw (response , TLV_TYPE_IP , & addr6 , sizeof (struct in_addr6 ));
88- }
89- met_api -> packet .add_tlv_uint (response , TLV_TYPE_ADDR_TYPE , ai_family );
90- }
91- else
92- {
93- dprintf ("Unable to resolve_host %s error: %x" , hostname , iResult );
94- }
125+ dprintf ("Error adding resolved host IP addresses to group. Something went really wrong." );
95126 }
96127
128+ dprintf ("Adding IP TLVs to Group TLV in response packet" );
129+ met_api -> packet .add_group (response , TLV_TYPE_RESOLVE_HOST_ENTRY , resolved_hosts );
130+ dprintf ("Freeing addrinfo" );
131+ freeaddrinfo (result );
132+
133+ done :
134+ dprintf ("Sending return packet for resolve_host" );
97135 met_api -> packet .transmit_response (iResult , remote , response );
98136 return ERROR_SUCCESS ;
99137}
@@ -103,33 +141,34 @@ DWORD request_resolve_hosts(Remote *remote, Packet *packet)
103141 Packet * response = met_api -> packet .create_response (packet );
104142 Tlv hostname = {0 };
105143 int index = 0 ;
106- int iResult ;
144+ int iResult = 0 ;
107145 u_short ai_family = met_api -> packet .get_tlv_value_uint (packet , TLV_TYPE_ADDR_TYPE );
108146
109147 while ( met_api -> packet .enum_tlv ( packet , index ++ , TLV_TYPE_HOST_NAME , & hostname ) == ERROR_SUCCESS )
110148 {
111- struct in_addr addr = {0 };
112- struct in6_addr addr6 = {0 };
149+ struct addrinfo * addr = NULL ;
150+
151+ iResult = resolve_host ((LPCSTR )hostname .buffer , ai_family , & addr );
113152
114- iResult = resolve_host (( LPCSTR ) hostname . buffer , ai_family , & addr , & addr6 );
153+ Packet * resolved_host_group = met_api -> packet . create_group ( );
115154
116- if (iResult == NO_ERROR )
155+ if (iResult != ERROR_SUCCESS || addr == NULL )
117156 {
118- if (ai_family == AF_INET )
119- {
120- met_api -> packet .add_tlv_raw (response , TLV_TYPE_IP , & addr , sizeof (struct in_addr ));
121- } else {
122- met_api -> packet .add_tlv_raw (response , TLV_TYPE_IP , & addr6 , sizeof (struct in_addr6 ));
123- }
157+ dprintf ("Unable to resolve_host %s error: %x" , hostname .buffer , iResult );
158+ goto done ;
124159 }
125- else
160+
161+ DWORD adding_host_ips = add_all_host_ips_to_group (& resolved_host_group , addr );
162+ if (adding_host_ips != ERROR_SUCCESS )
126163 {
127- dprintf ("Unable to resolve_host %s error: %x" , hostname . buffer , iResult );
128- met_api -> packet . add_tlv_raw ( response , TLV_TYPE_IP , NULL , 0 ) ;
164+ dprintf ("Error adding resolved host IP addresses to group. Something went really wrong." );
165+ goto done ;
129166 }
130- met_api -> packet .add_tlv_uint (response , TLV_TYPE_ADDR_TYPE , ai_family );
167+
168+ met_api -> packet .add_group (response , TLV_TYPE_RESOLVE_HOST_ENTRY , resolved_host_group );
131169 }
132170
133- met_api -> packet .transmit_response (NO_ERROR , remote , response );
171+ done :
172+ met_api -> packet .transmit_response (iResult , remote , response );
134173 return ERROR_SUCCESS ;
135174}
0 commit comments