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 `address_info` 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="address_info">The resulting addrinfo structure</param>
14+ /// <returns>0 on success, a Windows error code on error</returns>
15+ DWORD resolve_host (const LPCSTR hostname , UINT ai_family , struct addrinfo * * address_info )
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 (address_info == 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 , address_info );
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 ;
3850 }
39- else
51+ dprintf ("Resolved host '%s' successfully" , hostname );
52+
53+ dprintf ("Performing Win Socket cleanup" );
54+ iResult = WSACleanup ();
55+ if (iResult != ERROR_SUCCESS )
4056 {
41- switch (list -> ai_family ) {
57+ dprintf ("WSACleanup failed with return code %x" , iResult );
58+ return iResult ;
59+ }
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 or a list of hostnames to add to the group.</param>
70+ /// <returns>0 on success.</returns>
71+ DWORD add_all_host_ips_to_group (Packet * group , struct addrinfo * host )
72+ {
73+ if (group == NULL )
74+ {
75+ dprintf ("Null pointer provided as group" );
76+ return ERROR_INVALID_PARAMETER ;
77+ }
78+
79+ for (struct addrinfo * current = host ; current != NULL ; current = current -> ai_next )
80+ {
81+ switch (current -> ai_family )
82+ {
4283 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 ));
84+ dprintf ("Adding IP v4 Family to Group TLV" );
85+ met_api -> packet .add_tlv_uint (group , TLV_TYPE_ADDR_TYPE , (UINT )current -> ai_family );
86+ dprintf ("Adding IP v4 Address to Group TLV" );
87+ struct in_addr ipv4_addr = ((struct sockaddr_in * )(current -> ai_addr ))-> sin_addr ;
88+ met_api -> packet .add_tlv_raw (group , TLV_TYPE_IP , & ipv4_addr , sizeof (struct in_addr ));
89+ break ;
4690 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 :
91+ dprintf ("Adding IP v6 Family to Group TLV" );
92+ met_api -> packet .add_tlv_uint (group , TLV_TYPE_ADDR_TYPE , (UINT )current -> ai_family );
93+ dprintf ("Adding IP v6 Address to Group TLV" );
94+ struct in6_addr ipv6_addr = ((struct sockaddr_in6 * )(current -> ai_addr ))-> sin6_addr ;
95+ met_api -> packet .add_tlv_raw (group , TLV_TYPE_IP , & ipv6_addr , sizeof (struct in6_addr ));
5196 break ;
97+ default :
98+ dprintf ("Unknown family, skipping entry." );
99+ continue ;
52100 }
53101 }
54-
55- freeaddrinfo (list );
56- WSACleanup ();
57-
58- return iResult ;
102+ return ERROR_SUCCESS ;
59103}
60104
61105DWORD request_resolve_host (Remote * remote , Packet * packet )
62106{
63107 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 ;
108+ LPCSTR hostname = met_api -> packet .get_tlv_value_string (packet , TLV_TYPE_HOST_NAME );
109+ UINT ai_family = met_api -> packet .get_tlv_value_uint (packet , TLV_TYPE_ADDR_TYPE );
110+ DWORD iResult = ERROR_SUCCESS ;
69111
70- hostname = met_api -> packet .get_tlv_value_string (packet , TLV_TYPE_HOST_NAME );
112+ struct addrinfo * result ;
113+ iResult = resolve_host (hostname , ai_family , & result );
114+ if (iResult != ERROR_SUCCESS || result == NULL )
115+ {
116+ dprintf ("Could not resolve_host for '%s': %x" , hostname , iResult );
117+ goto done ;
118+ }
71119
72- if (!hostname )
120+ dprintf ("Creating group for resolve host entry" );
121+ Packet * resolved_hosts = met_api -> packet .create_group ();
122+ if (resolved_hosts == NULL )
73123 {
74- iResult = ERROR_INVALID_PARAMETER ;
75- dprintf ( "Hostname not set" ) ;
124+ dprintf ( "Could not create TLV Group" ) ;
125+ goto done ;
76126 }
77- else
127+
128+ if (add_all_host_ips_to_group (resolved_hosts , result ) != ERROR_SUCCESS )
78129 {
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- }
130+ dprintf ("Error adding resolved host IP addresses to group" );
95131 }
96132
133+ dprintf ("Adding IP TLVs to Group TLV in response packet" );
134+ met_api -> packet .add_group (response , TLV_TYPE_RESOLVE_HOST_ENTRY , resolved_hosts );
135+ dprintf ("Freeing addrinfo" );
136+ freeaddrinfo (result );
137+
138+ done :
139+ dprintf ("Sending return packet for resolve_host" );
97140 met_api -> packet .transmit_response (iResult , remote , response );
98141 return ERROR_SUCCESS ;
99142}
@@ -103,33 +146,34 @@ DWORD request_resolve_hosts(Remote *remote, Packet *packet)
103146 Packet * response = met_api -> packet .create_response (packet );
104147 Tlv hostname = {0 };
105148 int index = 0 ;
106- int iResult ;
107- u_short ai_family = met_api -> packet .get_tlv_value_uint (packet , TLV_TYPE_ADDR_TYPE );
149+ int iResult = 0 ;
150+ UINT ai_family = met_api -> packet .get_tlv_value_uint (packet , TLV_TYPE_ADDR_TYPE );
108151
109152 while ( met_api -> packet .enum_tlv ( packet , index ++ , TLV_TYPE_HOST_NAME , & hostname ) == ERROR_SUCCESS )
110153 {
111- struct in_addr addr = {0 };
112- struct in6_addr addr6 = {0 };
154+ struct addrinfo * addr = NULL ;
155+
156+ iResult = resolve_host ((LPCSTR )hostname .buffer , ai_family , & addr );
113157
114- iResult = resolve_host (( LPCSTR ) hostname . buffer , ai_family , & addr , & addr6 );
158+ Packet * resolved_host_group = met_api -> packet . create_group ( );
115159
116- if (iResult == NO_ERROR )
160+ if (iResult != ERROR_SUCCESS || addr == NULL )
117161 {
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- }
162+ dprintf ("Unable to resolve_host %s error: %x" , hostname .buffer , iResult );
163+ goto done ;
124164 }
125- else
165+
166+ if (add_all_host_ips_to_group (resolved_host_group , addr ) != ERROR_SUCCESS )
126167 {
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 ) ;
168+ dprintf ("Error adding resolved host IP addresses to group" );
169+ goto done ;
129170 }
130- met_api -> packet .add_tlv_uint (response , TLV_TYPE_ADDR_TYPE , ai_family );
171+
172+ met_api -> packet .add_group (response , TLV_TYPE_RESOLVE_HOST_ENTRY , resolved_host_group );
173+ if (addr != NULL ) { dprintf ("Freeing Address Info for hostname: %s" , hostname .buffer ); freeaddrinfo (addr ); }
131174 }
132175
133- met_api -> packet .transmit_response (NO_ERROR , remote , response );
176+ done :
177+ met_api -> packet .transmit_response (iResult , remote , response );
134178 return ERROR_SUCCESS ;
135179}
0 commit comments