2 * Copyright 2012 Haiku, Inc. All rights reserved.
3 * Distributed under the terms of the MIT License.
6 * Paweł Dziepak, pdziepak@quarnos.org
13 #include <sys/socket.h>
16 #include <AutoDeleter.h>
18 #include <SupportDefs.h>
20 #include "Definitions.h"
28 Serialize(char** _reply
, uint32
* _totalSize
, const struct addrinfo
* ai
)
30 uint32 addrsSize
= ai
== NULL
? 0 : sizeof(addrinfo
);
34 const struct addrinfo
* current
= ai
;
35 while (current
!= NULL
) {
36 if (current
->ai_canonname
!= NULL
)
37 namesSize
+= strlen(current
->ai_canonname
) + 1;
38 if (current
->ai_addr
!= NULL
) {
39 if (current
->ai_family
== AF_INET
)
40 socksSize
+= sizeof(sockaddr_in
);
42 socksSize
+= sizeof(sockaddr_in6
);
44 if (current
->ai_next
!= NULL
)
45 addrsSize
+= sizeof(addrinfo
);
46 current
= current
->ai_next
;
49 uint32 totalSize
= addrsSize
+ namesSize
+ socksSize
;
50 char* reply
= reinterpret_cast<char*>(malloc(totalSize
));
55 uint32 namePos
= addrsSize
;
56 uint32 sockPos
= addrsSize
+ namesSize
;
61 while (current
!= NULL
) {
62 memcpy(&temp
, current
, sizeof(addrinfo
));
64 if (current
->ai_canonname
!= NULL
) {
65 strcpy(reply
+ namePos
, current
->ai_canonname
);
66 uint32 nSize
= strlen(current
->ai_canonname
) + 1;
67 temp
.ai_canonname
= reinterpret_cast<char*>(namePos
);
70 if (current
->ai_addr
!= NULL
) {
71 if (current
->ai_family
== AF_INET
) {
72 memcpy(reply
+ sockPos
, current
->ai_addr
, sizeof(sockaddr_in
));
73 temp
.ai_addr
= reinterpret_cast<sockaddr
*>(sockPos
);
74 sockPos
+= sizeof(sockaddr_in
);
76 memcpy(reply
+ sockPos
, current
->ai_addr
, sizeof(sockaddr_in6
));
77 temp
.ai_addr
= reinterpret_cast<sockaddr
*>(sockPos
);
78 sockPos
+= sizeof(sockaddr_in6
);
82 addrinfo
* next
= current
->ai_next
;
84 temp
.ai_next
= reinterpret_cast<addrinfo
*>(addrPos
) + 1;
88 memcpy(reply
+ addrPos
, &temp
, sizeof(addrinfo
));
89 addrPos
+= sizeof(addrinfo
);
95 *_totalSize
= totalSize
;
101 GetAddrInfo(const char* buffer
)
103 const char* node
= buffer
[0] == '\0' ? NULL
: buffer
;
104 uint32 nodeSize
= node
!= NULL
? strlen(node
) + 1 : 1;
106 const char* service
= buffer
[nodeSize
] == '\0' ? NULL
: buffer
+ nodeSize
;
107 uint32 serviceSize
= service
!= NULL
? strlen(service
) + 1 : 1;
109 const struct addrinfo
* hints
110 = reinterpret_cast<const addrinfo
*>(buffer
+ nodeSize
+ serviceSize
);
113 status_t result
= getaddrinfo(node
, service
, hints
, &ai
);
115 return write_port(gReplyPort
, MsgError
, &result
, sizeof(result
));
119 result
= Serialize(&reply
, &totalSize
, ai
);
122 return write_port(gReplyPort
, MsgError
, &result
, sizeof(result
));
123 return write_port(gReplyPort
, MsgReply
, reply
, totalSize
);
131 ssize_t size
= port_buffer_size(gRequestPort
);
135 void* buffer
= malloc(size
);
138 MemoryDeleter
_(buffer
);
141 size
= read_port(gRequestPort
, &code
, buffer
, size
);
148 result
= GetAddrInfo(reinterpret_cast<char*>(buffer
));
152 result
= B_BAD_VALUE
;
153 write_port(gReplyPort
, MsgError
, &result
, sizeof(result
));
164 main(int argc
, char** argv
)
166 gRequestPort
= find_port(kPortNameReq
);
167 if (gRequestPort
< B_OK
) {
168 fprintf(stderr
, "%s\n", strerror(gRequestPort
));
172 gReplyPort
= find_port(kPortNameRpl
);
173 if (gReplyPort
< B_OK
) {
174 fprintf(stderr
, "%s\n", strerror(gReplyPort
));