Name | Executed | Routines | % | Executed | Lines | % | Unexecuted |
/home/matt/eu/rds/include/std/net/dns.e | 2 | 2 | 100.00% | 35 | 35 | 100.00% | 0 |
Routine | Executed | Lines | Unexecuted | |
host_by_addr() | 2 | 2 | 100.00% | 0 |
host_by_name() | 2 | 2 | 100.00% | 0 |
# | Executed | |
1 | --**** | |
2 | -- == DNS | |
3 | -- | |
4 | -- Based on EuNet project, version 1.3.2 at SourceForge. | |
5 | -- | |
6 | -- < | |
7 | -- | |
8 | ||
9 | namespace dns | |
10 | ||
11 | include std/socket.e | |
12 | include std/get.e | |
13 | ||
14 | 2 | constant BLOCK_SIZE = 4096 |
15 | 2 | enum M_SOCK_GETHOSTBYNAME=79, M_SOCK_GETHOSTBYADDR |
16 | ||
17 | --**** | |
18 | -- === Constants | |
19 | ||
20 | 2 | public enum ADDR_FLAGS, ADDR_FAMILY, ADDR_TYPE, ADDR_PROTOCOL, ADDR_ADDRESS |
21 | ||
22 | 2 | public enum HOST_OFFICIAL_NAME, HOST_ALIASES, HOST_IPS, HOST_TYPE |
23 | ||
24 | public constant | |
25 | 2 | DNS_QUERY_STANDARD = 0, |
26 | 2 | DNS_QUERY_ACCEPT_TRUNCATED_RESPONSE = 1, |
27 | 2 | DNS_QUERY_USE_TCP_ONLY = 2, |
28 | 2 | DNS_QUERY_NO_RECURSION = 4, |
29 | 2 | DNS_QUERY_BYPASS_CACHE = 8, |
30 | 2 | DNS_QUERY_NO_WIRE_QUERY = 16, |
31 | 2 | DNS_QUERY_NO_LOCAL_NAME = 32, |
32 | 2 | DNS_QUERY_NO_HOSTS_FILE = 64, |
33 | 2 | DNS_QUERY_NO_NETBT = 128, |
34 | 2 | DNS_QUERY_WIRE_ONLY = 256, |
35 | 2 | DNS_QUERY_RETURN_MESSAGE = 512, |
36 | 2 | DNS_QUERY_TREAT_AS_FQDN = #1000, |
37 | 2 | DNS_QUERY_DONT_RESET_TTL_VALUES = #100000, |
38 | 2 | DNS_QUERY_RESERVED = #FF000000, |
39 | ||
40 | 2 | NS_C_IN = 1, |
41 | 2 | NS_C_ANY = 255, |
42 | 2 | NS_KT_RSA = 1, |
43 | 2 | NS_KT_DH = 2, |
44 | 2 | NS_KT_DSA = 3, |
45 | 2 | NS_KT_PRIVATE = 254, |
46 | 2 | NS_T_A = 1, |
47 | 2 | NS_T_NS = 2, |
48 | 2 | NS_T_PTR = 12, |
49 | 2 | NS_T_MX = 15, |
50 | 2 | NS_T_AAAA = 28, |
51 | 2 | NS_T_A6 = 38, |
52 | 2 | NS_T_ANY = 255 |
53 | ||
54 | --**** | |
55 | -- === General Routines | |
56 | ||
57 | /* | |
58 | ifdef WIN32 then | |
59 | constant dnsdll_ = open_dll("dnsapi.dll") | |
60 | ||
61 | constant getaddrinfo_ = define_c_func(sockdll_,"getaddrinfo",{C_POINTER,C_POINTER,C_POINTER,C_POINTER},C_INT) | |
62 | constant dnsquery_ = define_c_func(dnsdll_,"DnsQuery_A",{C_POINTER,C_USHORT,C_INT,C_POINTER,C_POINTER,C_POINTER},C_INT) | |
63 | constant dnsrlfree_ = define_c_proc(dnsdll_,"DnsRecordListFree",{C_POINTER,C_INT}) | |
64 | constant dnsexpand_ = -1 | |
65 | constant freeaddrinfo_ = define_c_proc(sockdll_,"freeaddrinfo",{C_POINTER}) | |
66 | ||
67 | elsifdef LINUX or SUNOS then | |
68 | constant dnsdll_ = open_dll("libresolv.so") | |
69 | ||
70 | elsifdef FREEBSD then | |
71 | constant dnsdll_ = open_dll("libc.so") | |
72 | ||
73 | elsifdef OSX then | |
74 | constant dnsdll_ = open_dll("libresolv.dylib") | |
75 | ||
76 | end ifdef | |
77 | ||
78 | ifdef UNIX then | |
79 | constant dnsquery_ = define_c_func(dnsdll_,"res_query",{C_POINTER,C_INT,C_INT,C_POINTER,C_INT},C_INT) | |
80 | constant dnsrlfree_ = -1 | |
81 | constant dnsexpand_ = define_c_func(dnsdll_,"dn_expand",{C_POINTER,C_POINTER,C_POINTER,C_POINTER,C_INT},C_INT) | |
82 | constant getaddrinfo_ = define_c_func(dll_,"getaddrinfo",{C_POINTER,C_POINTER,C_POINTER,C_POINTER},C_INT) | |
83 | constant freeaddrinfo_ = define_c_proc(dll_,"freeaddrinfo",{C_POINTER}) | |
84 | end ifdef | |
85 | ||
86 | function _socket_trim(sequence s) | |
87 | atom c | |
88 | sequence rs | |
89 | rs = s | |
90 | c = 1 | |
91 | while c <= length(s) and rs[c] <= 32 do | |
92 | c = c + 1 | |
93 | end while | |
94 | rs = rs[c .. $] | |
95 | c = length(rs) | |
96 | while c > 0 and rs[c] <= 32 do | |
97 | c = c - 1 | |
98 | end while | |
99 | rs = rs[1..c] | |
100 | return rs | |
101 | end function | |
102 | ||
103 | -- Returns a set of sequences of {ip_addr, q_type, order} resolving the IP address for | |
104 | -- the given domain name and/or host. | |
105 | -- At present, only A,MX,and NS queries are supported. | |
106 | -- Error 9501 = No record found | |
107 | ||
108 | function unix_dnsquery(sequence dname, integer q_type) | |
109 | atom nameptr, rtnptr, success, ptrptr, dnameptr, qlen | |
110 | atom answer_start, answer_end, num_as_rec, num_qr_rec | |
111 | sequence rtn, line, subx | |
112 | object temp | |
113 | ||
114 | nameptr = allocate_string(dname&0) | |
115 | rtnptr = allocate(BLOCK_SIZE*8) | |
116 | success = c_func(dnsquery_,{nameptr,NS_C_IN,q_type,rtnptr,BLOCK_SIZE*8}) | |
117 | if success < 0 then | |
118 | free(nameptr) | |
119 | free(rtnptr) | |
120 | return success | |
121 | end if | |
122 | -- The parsing of rtnptr is significantly more difficult in Linux than | |
123 | -- in Windows. Much of the code that follows is based on Postfix-2.5.1/ | |
124 | -- src/dns/dns_lookup.c. | |
125 | if success > BLOCK_SIZE * 8 then -- The Answer has been truncated & is invalid. | |
126 | free(nameptr) | |
127 | free(rtnptr) | |
128 | return -2 | |
129 | end if | |
130 | -- Size of Header = 12 bytes. # Query = [5..6], # Answer = [7..8], # Auth = [9..10] | |
131 | -- # Res = [11..12] | |
132 | num_qr_rec = (peek(rtnptr+4)*256)+peek(rtnptr+5) | |
133 | num_as_rec = (peek(rtnptr+6)*256)+peek(rtnptr+7) | |
134 | if num_as_rec = 0 then | |
135 | free(nameptr) | |
136 | free(rtnptr) | |
137 | return 9501 -- No Data | |
138 | end if | |
139 | ptrptr = rtnptr + 12 -- Start of query record | |
140 | dnameptr = allocate(1024) | |
141 | for ctr = 1 to num_qr_rec do | |
142 | qlen = c_func(dnsexpand_,{rtnptr,rtnptr+success,ptrptr,dnameptr,1024}) | |
143 | if qlen < 0 then | |
144 | free(dnameptr) | |
145 | free(nameptr) | |
146 | free(rtnptr) | |
147 | return qlen | |
148 | end if | |
149 | ptrptr = ptrptr + qlen + 4 | |
150 | end for | |
151 | answer_start = ptrptr | |
152 | answer_end = rtnptr + success | |
153 | ||
154 | -- Now we're finally at the answer section | |
155 | rtn = {} | |
156 | for seq = 1 to num_as_rec do | |
157 | line = repeat(0,8) | |
158 | subx = repeat(0,32) | |
159 | if ptrptr >= answer_end then | |
160 | free(dnameptr) | |
161 | free(nameptr) | |
162 | free(rtnptr) | |
163 | return -4 | |
164 | end if | |
165 | qlen = c_func(dnsexpand_,{rtnptr,answer_end,ptrptr,dnameptr,1024}) | |
166 | if qlen < 0 then | |
167 | free(dnameptr) | |
168 | free(nameptr) | |
169 | free(rtnptr) | |
170 | return -5 | |
171 | end if | |
172 | line[2] = peek_string(dnameptr) | |
173 | ptrptr = ptrptr + qlen | |
174 | if ptrptr+10 >= answer_end then | |
175 | free(dnameptr) | |
176 | free(nameptr) | |
177 | free(rtnptr) | |
178 | return -4 | |
179 | end if | |
180 | line[3] = (peek(ptrptr)*256)+peek(ptrptr+1) -- type | |
181 | line[7] = (peek(ptrptr+2)*256)+peek(ptrptr+3) -- Class | |
182 | line[6] = (peek(ptrptr+4)*256*256*256)+(peek(ptrptr+5)*256*256)+ | |
183 | (peek(ptrptr+6)*256)+peek(ptrptr+7) -- TTL | |
184 | line[4] = (peek(ptrptr+8)*256)+peek(ptrptr+9) -- Data Length | |
185 | ptrptr = ptrptr + 10 | |
186 | if ptrptr + line[4] - 1 >= answer_end then | |
187 | free(dnameptr) | |
188 | free(nameptr) | |
189 | free(rtnptr) | |
190 | return -4 | |
191 | end if | |
192 | if line[3] = NS_T_NS then | |
193 | qlen = c_func(dnsexpand_,{rtnptr,answer_end,ptrptr,dnameptr,1024}) | |
194 | if qlen > 0 then | |
195 | subx[1] = peek_string(dnameptr) | |
196 | temp = unix_dnsquery(subx[1],NS_T_A) | |
197 | if atom(temp) then | |
198 | rtn = append(rtn,{subx[1],line[3],seq}) | |
199 | else | |
200 | for ctr = 1 to length(temp) do | |
201 | rtn = append(rtn,{temp[ctr][1],line[3],seq+ctr-1}) | |
202 | end for | |
203 | end if | |
204 | end if | |
205 | elsif line[3] = NS_T_MX then | |
206 | subx[2] = (peek(ptrptr)*256)+peek(ptrptr+1) -- Priority | |
207 | qlen = c_func(dnsexpand_,{rtnptr,answer_end,ptrptr+2,dnameptr,1024}) | |
208 | if qlen > 0 then | |
209 | subx[1] = peek_string(dnameptr) | |
210 | temp = unix_dnsquery(subx[1],NS_T_A) | |
211 | if atom(temp) then | |
212 | rtn = append(rtn,{subx[1],line[3],subx[2]}) | |
213 | else | |
214 | for ctr = 1 to length(temp) do | |
215 | rtn = append(rtn,{temp[ctr][1],line[3],subx[2]+ctr-1}) | |
216 | end for | |
217 | end if | |
218 | end if | |
219 | elsif line[3] = NS_T_A and line[4] >= 4 then | |
220 | subx[1] = sprintf("%d.%d.%d.%d",{peek(ptrptr),peek(ptrptr+1), | |
221 | peek(ptrptr+2),peek(ptrptr+3)}) | |
222 | if q_type = NS_T_ANY or q_type = NS_T_A then | |
223 | rtn = append(rtn,{subx[1],line[3],seq}) | |
224 | end if | |
225 | elsif line[3] = NS_T_PTR then | |
226 | ||
227 | end if | |
228 | ptrptr = ptrptr + line[4] | |
229 | ||
230 | end for | |
231 | ||
232 | -- Finally, we're done. | |
233 | free(dnameptr) | |
234 | free(nameptr) | |
235 | free(rtnptr) | |
236 | ||
237 | return rtn | |
238 | ||
239 | end function | |
240 | ||
241 | ||
242 | function windows_dnsquery(sequence dname, integer q_type, atom options) | |
243 | -- NOTE: This function does not work on Windows versions below Windows 2000. | |
244 | ||
245 | atom success,nameptr, rtnptr, recptr, seq | |
246 | sequence rtn, line, subx | |
247 | object temp | |
248 | ||
249 | if dnsquery_ < 0 then | |
250 | return -999 | |
251 | end if | |
252 | ||
253 | nameptr = allocate_string(dname) | |
254 | rtnptr = allocate(4) | |
255 | success = c_func(dnsquery_,{nameptr,q_type,options,0,rtnptr,0}) | |
256 | if success != 0 then | |
257 | free(nameptr) | |
258 | free(rtnptr) | |
259 | return success | |
260 | end if | |
261 | rtn = {} | |
262 | recptr = peek4u(rtnptr) | |
263 | seq = 1 | |
264 | while recptr > 0 do | |
265 | line = repeat(0,8) | |
266 | subx = repeat(0,32) | |
267 | line[1]=peek4u(recptr) -- Pointer to the next record | |
268 | line[2]=peek4u(recptr+4) -- Pointer to the name string | |
269 | line[3]=peek(recptr+8)+(peek(recptr+9)*256) -- type | |
270 | line[4]=peek(recptr+10)+(peek(recptr+11)*256) -- Data Length | |
271 | line[5]=peek4u(recptr+12) -- Flags | |
272 | line[6]=peek4u(recptr+16) -- TTL | |
273 | line[7]=peek4u(recptr+20) -- reserved | |
274 | if line[3] = NS_T_MX then | |
275 | subx[1] = peek_string(peek4u(recptr+24)) -- Mail server name | |
276 | subx[2] = peek(recptr+28)+(peek(recptr+29)*256) -- Preference | |
277 | temp = windows_dnsquery(subx[1],NS_T_A,options) | |
278 | if atom(temp) then | |
279 | rtn = append(rtn,{subx[1],line[3],subx[2]}) | |
280 | else | |
281 | for ctr = 1 to length(temp) do | |
282 | rtn = append(rtn,{temp[ctr][1],line[3],subx[2]+ctr-1}) | |
283 | end for | |
284 | end if | |
285 | elsif line[3] = NS_T_NS then | |
286 | subx[1] = peek_string(peek4u(recptr+24)) -- NS server name | |
287 | temp = windows_dnsquery(subx[1],NS_T_A,options) | |
288 | if atom(temp) then | |
289 | rtn = append(rtn,{subx[1],line[3],seq}) | |
290 | else | |
291 | for ctr = 1 to length(temp) do | |
292 | rtn = append(rtn,{temp[ctr][1],line[3],seq+ctr-1}) | |
293 | end for | |
294 | end if | |
295 | elsif line[3] = NS_T_A then | |
296 | subx[1] = sprintf("%d.%d.%d.%d",{peek(recptr+24),peek(recptr+25), | |
297 | peek(recptr+26),peek(recptr+27)}) | |
298 | if q_type = NS_T_ANY or q_type = NS_T_A then | |
299 | rtn = append(rtn,{subx[1],line[3],seq}) | |
300 | end if | |
301 | elsif line[3] = NS_T_PTR then | |
302 | ||
303 | end if | |
304 | recptr = line[1] | |
305 | seq = seq + 1 | |
306 | end while | |
307 | c_proc(dnsrlfree_,{peek4u(rtnptr),1}) | |
308 | free(nameptr) | |
309 | free(rtnptr) | |
310 | ||
311 | return rtn | |
312 | ||
313 | end function | |
314 | ||
315 | ||
316 | --** | |
317 | -- Query DNS info. | |
318 | -- | |
319 | -- Parameters: | |
320 | -- # ##dname## : a string, the name to look up | |
321 | -- # ##q_type## : an integer, the type of lookup requested | |
322 | -- # ##options## : an atom, | |
323 | -- | |
324 | -- Returns: | |
325 | -- An **object**, either a negative integer on error, or a sequence of sequences in the form {{string ip_address, integer query_type, integer priority},...}. | |
326 | -- | |
327 | -- Comments: | |
328 | -- | |
329 | -- For standard A record lookups, getaddrinfo is preferred. | |
330 | -- But sometimes, more advanced DNS lookups are required. Eventually, | |
331 | -- this routine will support all types of DNS lookups. In Euphoria | |
332 | -- 4.0, only NS, MX, and A lookups are accepted. | |
333 | -- | |
334 | -- Example 1: | |
335 | -- | |
336 | -- result = dnsquery("yahoo.com",NS_T_MX,0) | |
337 | -- if atom(result) then | |
338 | -- puts(1,"Uh, oh!") | |
339 | -- else | |
340 | -- for ctr = 1 to length(result) do | |
341 | -- printf(1,"%s\t%d\t%d\n",result[ctr]) | |
342 | -- end for | |
343 | -- end if | |
344 | -- | |
345 | -- | |
346 | -- See Also: | |
347 | -- [[:getaddrinfo]], [[:gethostbyname]], [[:getmxrr]], [[:getnsrr]] | |
348 | ||
349 | public function dnsquery(sequence dname, integer q_type, atom options) | |
350 | ifdef WIN32 then | |
351 | return windows_dnsquery(dname, q_type, options) | |
352 | elsifdef UNIX then | |
353 | return unix_dnsquery(dname,q_type) | |
354 | end ifdef | |
355 | ||
356 | return -999 -- TODO: -999 or -1? | |
357 | end function | |
358 | ||
359 | ------------------------------------------------------------------------------- | |
360 | -- getmxrr | |
361 | ------------------------------------------------------------------------------- | |
362 | ||
363 | --** | |
364 | -- Find a mail server for a given domain. If none can be found, | |
365 | -- attempt a smart query by looking up common variations on | |
366 | -- domain_name. | |
367 | -- | |
368 | -- Parameters: | |
369 | -- # ##dname## : a string, the name to look up | |
370 | -- # ##options## : an atom, | |
371 | -- | |
372 | -- Returns: | |
373 | -- | |
374 | -- An **object**, either a negative integer on error, or a sequence of sequences in the form {{string ip_address, integer query_type, integer priority},...}. | |
375 | -- | |
376 | -- See Also: | |
377 | -- [[:dnsquery]] | |
378 | ||
379 | public function getmxrr(sequence dname, atom options) | |
380 | object rtn | |
381 | ||
382 | -- Error 9003 = MS: RCODE_NAME_ERROR - Something's there, but it's not exact. | |
383 | -- Error 9501 = No Data Found | |
384 | ||
385 | dname = _socket_trim(dname) | |
386 | rtn = dnsquery(dname,NS_T_MX,options) | |
387 | if sequence(rtn) and length(rtn)>0 then | |
388 | return rtn | |
389 | end if | |
390 | if rtn = 9501 or rtn = 9003 or rtn = -1 or | |
391 | (sequence(rtn) and length(rtn)=0) then | |
392 | rtn = dnsquery("mail."&dname,NS_T_MX,options) | |
393 | end if | |
394 | return rtn | |
395 | end function | |
396 | ||
397 | ------------------------------------------------------------------------------- | |
398 | -- getnsrr | |
399 | ------------------------------------------------------------------------------- | |
400 | ||
401 | --** | |
402 | -- Find a name server for a given domain. If none can be found, | |
403 | -- attempt a smart query by looking up common variations on | |
404 | -- domain_name. | |
405 | -- | |
406 | -- Parameters: | |
407 | -- # ##dname## : a string, the name to look up | |
408 | -- # ##options## : an atom, | |
409 | -- | |
410 | -- Returns: | |
411 | -- An **object**, either a negative integer on error, or a sequence of sequences in the form {{string ip_address, integer query_type, integer priority},...}. | |
412 | -- | |
413 | -- See Also: | |
414 | -- [[:dnsquery]] | |
415 | ||
416 | public function getnsrr(sequence dname, atom options) | |
417 | return dnsquery(dname,NS_T_NS,options) | |
418 | end function | |
419 | ||
420 | ------------------------------------------------------------------------------- | |
421 | -- GetAddrInfo | |
422 | ------------------------------------------------------------------------------- | |
423 | -- Returns a sequence of sequences {atom flags, atom family, atom socktype, atom protocol, sequence inet_addr} | |
424 | -- on success or an error code on failure | |
425 | ||
426 | --memset(&hints, 0, sizeof(hints)); | |
427 | --hints.ai_flags = AI_NUMERICHOST; | |
428 | --hints.ai_family = PF_UNSPEC; | |
429 | --hints.ai_socktype = 0; | |
430 | --hints.ai_protocol = 0; | |
431 | --hints.ai_addrlen = 0; | |
432 | --hints.ai_canonname = NULL; | |
433 | --hints.ai_addr = NULL; | |
434 | --hints.ai_next = NULL; | |
435 | --getaddrinfo(ip, port, &hints, &aiList) | |
436 | --nodename A pointer to a NULL-terminated ANSI string that contains a host (node) name or a numeric host address string. For the Internet protocol, the numeric host address string is a dotted-decimal IPv4 address or an IPv6 hex address. | |
437 | --servname A pointer to a NULL-terminated ANSI string that contains either a service name or port number represented as a string. | |
438 | --hints A pointer to an addrinfo structure that provides hints about the type of socket the caller supports. See Remarks. | |
439 | --res A pointer to a linked list of one or more addrinfo structures that contains response information about the host. | |
440 | ||
441 | function unix_getaddrinfo(object node, object service, object hints) | |
442 | atom addrinfo, success, node_ptr, service_ptr, hints_ptr, addrinfo_ptr, | |
443 | svcport, cpos | |
444 | sequence rtn, val | |
445 | ||
446 | hints = hints -- TODO -- not implemented. | |
447 | addrinfo = allocate(32) | |
448 | poke(addrinfo,repeat(0,32)) | |
449 | if sequence(node) then | |
450 | node_ptr = allocate_string(node) | |
451 | else | |
452 | node_ptr = node | |
453 | end if | |
454 | svcport = 0 | |
455 | if sequence(service) then | |
456 | service_ptr = allocate_string(service) | |
457 | val = value(service) | |
458 | if val[1] = GET_SUCCESS then | |
459 | svcport = val[2] | |
460 | end if | |
461 | else | |
462 | service_ptr = service | |
463 | if service > 0 and service <= #FFFF then | |
464 | svcport = service | |
465 | service_ptr = 0 | |
466 | end if | |
467 | end if | |
468 | hints_ptr = 0 -- Not yet implemented | |
469 | success = c_func(getaddrinfo_,{node_ptr,service_ptr,hints_ptr,addrinfo}) | |
470 | if success != 0 then | |
471 | free(addrinfo) | |
472 | if sequence(node) then free(node_ptr) end if | |
473 | if sequence(service) then free(service_ptr) end if | |
474 | return 0 | |
475 | end if | |
476 | rtn = {} | |
477 | -- addrinfo is a pointer to a pointer to a structure in Linux. | |
478 | addrinfo_ptr = peek4u(addrinfo) | |
479 | -- 27 Nov 2007: Only one addrinfo structure is supported | |
480 | -- while addrinfo_ptr != 0 do | |
481 | rtn = append(rtn,{ | |
482 | peek4u(addrinfo_ptr), | |
483 | peek4u(addrinfo_ptr+4), | |
484 | peek4u(addrinfo_ptr+8), | |
485 | peek4u(addrinfo_ptr+12), | |
486 | get_sockaddr(peek4u(addrinfo_ptr+20)) | |
487 | }) | |
488 | ||
489 | addrinfo_ptr = peek4u(addrinfo_ptr+28) | |
490 | -- end while | |
491 | ||
492 | c_proc(freeaddrinfo_,{peek4u(addrinfo)}) | |
493 | ||
494 | if length(rtn[1][5])=0 and sequence(node) then | |
495 | rtn[1][5] = gethostbyname(node) | |
496 | if sequence(service) and svcport = 0 then | |
497 | rtn[1][5] = rtn[1][5] & sprintf(":%d",getservbyname(service)) | |
498 | elsif svcport > 0 then | |
499 | rtn[1][5] = rtn[1][5] & sprintf(":%d",svcport) | |
500 | end if | |
501 | elsif svcport > 0 then | |
502 | cpos = find(':',rtn[1][5]) | |
503 | if cpos = 0 or cpos = length(rtn[1][5]) or | |
504 | eu:compare(rtn[1][5][$ - 1 .. $],":0")=0 then | |
505 | if cpos = 0 then | |
506 | rtn[1][5] = rtn[1][5] & sprintf(":%d",svcport) | |
507 | else | |
508 | rtn[1][5] = rtn[1][5][1..cpos-1] & sprintf(":%d",svcport) | |
509 | end if | |
510 | end if | |
511 | end if | |
512 | ||
513 | free(addrinfo) | |
514 | ||
515 | return rtn | |
516 | end function | |
517 | ||
518 | function windows_getaddrinfo(object node, object service, object hints) | |
519 | return unix_getaddrinfo(node, service, hints) | |
520 | end function | |
521 | ||
522 | --** | |
523 | -- Retrieve information about a given server name and named service. | |
524 | -- | |
525 | -- Parameters: | |
526 | -- # ##node## : an object, ??? | |
527 | -- # ##service## : an object, ??? | |
528 | -- # ##hints## : an object, currently not used | |
529 | -- | |
530 | -- Returns: | |
531 | -- A **sequence**, of sequences containing the requested information. | |
532 | -- The inner sequences have fields that can be accessed with public constants | |
533 | -- | |
534 | -- * ADDR_FLAGS | |
535 | -- * ADDR_FAMILY | |
536 | -- * ADDR_TYPE | |
537 | -- * ADDR_PROTOCOL | |
538 | -- * ADDR_ADDRESS | |
539 | -- | |
540 | -- Comments: | |
541 | -- Different DNS servers may return conflicting information about a | |
542 | -- name, but getaddrinfo will only return the first. Future | |
543 | -- versions will allow multiple entries to be returned, so this | |
544 | -- return format will keep programs using this library from breaking | |
545 | -- when the functionality is added. The hints parameter is not | |
546 | -- currently used. Service may be either a string containing the | |
547 | -- service name, a string containing the port number, or an integer | |
548 | -- port number between 0 and 65535. | |
549 | -- | |
550 | -- Example 1: | |
551 | -- | |
552 | -- puts(1,"The IP address and port for http://www.yahoo.com is "& | |
553 | -- getaddrinfo("www.yahoo.com","http",0)&"\n") | |
554 | -- | |
555 | ||
556 | public function getaddrinfo(object node, object service, object hints) | |
557 | ifdef WIN32 then | |
558 | return windows_getaddrinfo(node,service,hints) | |
559 | elsifdef UNIX then | |
560 | return unix_getaddrinfo(node,service,hints) | |
561 | end ifdef | |
562 | ||
563 | return -999 | |
564 | end function | |
565 | */ | |
566 | ||
567 | --** | |
568 | -- Get the host information by name. | |
569 | -- | |
570 | -- Parameters: | |
571 | -- # ##name## : host name | |
572 | -- | |
573 | -- Returns: | |
574 | -- A ##sequence##, containing | |
575 | -- | |
576 | -- { | |
577 | -- official name, | |
578 | -- { alias1, alias2, ... }, | |
579 | -- { ip1, ip2, ... }, | |
580 | -- address_type | |
581 | -- } | |
582 | -- | |
583 | -- | |
584 | -- Example 1: | |
585 | -- | |
586 | -- object data = host_by_name("www.google.com") | |
587 | -- -- data = { | |
588 | -- -- "www.l.google.com", | |
589 | -- -- { | |
590 | -- -- "www.google.com" | |
591 | -- -- }, | |
592 | -- -- { | |
593 | -- -- "74.125.93.104", | |
594 | -- -- "74.125.93.147", | |
595 | -- -- ... | |
596 | -- -- }, | |
597 | -- -- 2 | |
598 | -- -- } | |
599 | -- | |
600 | -- | |
601 | ||
602 | 4 | |
603 | 4 | return machine_func(M_SOCK_GETHOSTBYNAME, { name }) |
604 | end function | |
605 | ||
606 | --** | |
607 | -- Get the host information by address. | |
608 | -- | |
609 | -- Parameters: | |
610 | -- # ##address## : host address | |
611 | -- | |
612 | -- Returns: | |
613 | -- A ##sequence##, containing | |
614 | -- | |
615 | -- { | |
616 | -- official name, | |
617 | -- { alias1, alias2, ... }, | |
618 | -- { ip1, ip2, ... }, | |
619 | -- address_type | |
620 | -- } | |
621 | -- | |
622 | -- | |
623 | -- Example 1: | |
624 | -- | |
625 | -- object data = host_by_addr("74.125.93.147") | |
626 | -- -- data = { | |
627 | -- -- "www.l.google.com", | |
628 | -- -- { | |
629 | -- -- "www.google.com" | |
630 | -- -- }, | |
631 | -- -- { | |
632 | -- -- "74.125.93.104", | |
633 | -- -- "74.125.93.147", | |
634 | -- -- ... | |
635 | -- -- }, | |
636 | -- -- 2 | |
637 | -- -- } | |
638 | -- | |
639 | -- | |
640 | ||
641 | 1 | |
642 | 1 | return machine_func(M_SOCK_GETHOSTBYADDR, { address }) |
643 | end function |