Rev 1514 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 1514 | Rev 1542 | ||
---|---|---|---|
Line 5... | Line 5... | ||
5 | include '../struct.inc' |
5 | include '../struct.inc' |
6 | include '../proc32.inc' |
6 | include '../proc32.inc' |
7 | include '../macros.inc' |
7 | include '../macros.inc' |
8 | purge section,mov,add,sub |
8 | purge section,mov,add,sub |
Line 9... | Line 9... | ||
9 | 9 | ||
Line 10... | Line 10... | ||
10 | include 'network.inc' |
10 | include '../network.inc' |
Line 11... | Line 11... | ||
11 | 11 | ||
12 | section '.flat' code readable align 16 |
12 | section '.flat' code readable align 16 |
Line 27... | Line 27... | ||
27 | mov [mem.free], ebx |
27 | mov [mem.free], ebx |
28 | mov [mem.realloc], ecx |
28 | mov [mem.realloc], ecx |
29 | mov [dll.load], edx |
29 | mov [dll.load], edx |
30 | mov [DNSrequestID], 1 |
30 | mov [DNSrequestID], 1 |
31 | stdcall edx, @IMPORT |
31 | stdcall edx, @IMPORT |
- | 32 | xor eax, eax |
|
32 | ret 4 |
33 | ret |
Line 33... | Line 34... | ||
33 | 34 | ||
34 | ;;===========================================================================;; |
35 | ;;===========================================================================;; |
35 | ;; in_addr_t __stdcall inet_addr(__in const char* hostname); ;; |
36 | ;; in_addr_t __stdcall inet_addr(__in const char* hostname); ;; |
36 | inet_addr: ;; |
37 | inet_addr: ;; |
Line 255... | Line 256... | ||
255 | mov word [edi], si |
256 | mov word [edi], si |
256 | add edi, 2 |
257 | add edi, 2 |
257 | ret |
258 | ret |
Line 258... | Line 259... | ||
258 | 259 | ||
259 | struct __gai_reqdata |
260 | struct __gai_reqdata |
260 | socket dd ? |
261 | socketnum dd ? |
261 | ; external code should not look on rest of this structure, |
262 | ; external code should not look on rest of this structure, |
262 | ; it is internal for getaddrinfo_start/process/abort |
263 | ; it is internal for getaddrinfo_start/process/abort |
263 | reqid dw ? ; DNS request ID |
264 | reqid dw ? ; DNS request ID |
264 | socktype db ? ; SOCK_* or 0 for any |
265 | socktype db ? ; SOCK_* or 0 for any |
Line 277... | Line 278... | ||
277 | ;;---------------------------------------------------------------------------;; |
278 | ;;---------------------------------------------------------------------------;; |
278 | ;? Get a list of IP addresses and port numbers for given host and service ;; |
279 | ;? Get a list of IP addresses and port numbers for given host and service ;; |
279 | ;;---------------------------------------------------------------------------;; |
280 | ;;---------------------------------------------------------------------------;; |
280 | ;> first parameter (optional) = host name ;; |
281 | ;> first parameter (optional) = host name ;; |
281 | ;> second parameter (optional) = service name (decimal number for now) ;; |
282 | ;> second parameter (optional) = service name (decimal number for now) ;; |
282 | ;> third parameter (optional) = hints for socket type ;; |
283 | ;> third parameter (optional) = hints for socketnum type ;; |
283 | ;> fourth parameter = pointer to result (head of L1-list) ;; |
284 | ;> fourth parameter = pointer to result (head of L1-list) ;; |
284 | ;;---------------------------------------------------------------------------;; |
285 | ;;---------------------------------------------------------------------------;; |
285 | ;< eax = 0 on success / one of EAI_ codes on error ;; |
286 | ;< eax = 0 on success / one of EAI_ codes on error ;; |
286 | ;;===========================================================================;; |
287 | ;;===========================================================================;; |
287 | ; 0. Save used registers for __stdcall. |
288 | ; 0. Save used registers for __stdcall. |
Line 423... | Line 424... | ||
423 | push EAI_FAMILY |
424 | push EAI_FAMILY |
424 | pop eax |
425 | pop eax |
425 | jecxz @f |
426 | jecxz @f |
426 | cmp [ecx+addrinfo.ai_family], edi |
427 | cmp [ecx+addrinfo.ai_family], edi |
427 | jz @f |
428 | jz @f |
428 | cmp [ecx+addrinfo.ai_family], PF_INET |
429 | cmp [ecx+addrinfo.ai_family], AF_INET4 |
429 | jnz .ret |
430 | jnz .ret |
430 | @@: |
431 | @@: |
431 | ; 1e. Valid combinations for ai_socktype/ai_protocol: 0/0 for any or |
432 | ; 1e. Valid combinations for ai_socktype/ai_protocol: 0/0 for any or |
432 | ; SOCK_STREAM/IPPROTO_TCP, SOCK_DGRAM/IPPROTO_UDP |
433 | ; SOCK_STREAM/IPPROTO_TCP, SOCK_DGRAM/IPPROTO_UDP |
433 | ; (raw sockets are not yet supported by the kernel) |
434 | ; (raw socketnums are not yet supported by the kernel) |
434 | xor edx, edx ; assume 0=any if no hints |
435 | xor edx, edx ; assume 0=any if no hints |
435 | jecxz .socket_type_ok |
436 | jecxz .socketnum_type_ok |
436 | mov edx, [ecx+addrinfo.ai_socktype] |
437 | mov edx, [ecx+addrinfo.ai_socktype] |
437 | mov esi, [ecx+addrinfo.ai_protocol] |
438 | mov esi, [ecx+addrinfo.ai_protocol] |
438 | ; 1f. Test for ai_socktype=0 and ai_protocol=0. |
439 | ; 1f. Test for ai_socktype=0 and ai_protocol=0. |
439 | test edx, edx |
440 | test edx, edx |
440 | jnz .check_socktype |
441 | jnz .check_socktype |
441 | test esi, esi |
442 | test esi, esi |
442 | jz .socket_type_ok |
443 | jz .socketnum_type_ok |
443 | ; 1g. ai_socktype=0, ai_protocol is nonzero. |
444 | ; 1g. ai_socktype=0, ai_protocol is nonzero. |
444 | push EAI_SERVICE |
445 | push EAI_SERVICE |
445 | pop eax |
446 | pop eax |
446 | inc edx ; edx = SOCK_STREAM |
447 | inc edx ; edx = SOCK_STREAM |
447 | cmp esi, IPPROTO_TCP |
448 | cmp esi, IPPROTO_TCP |
448 | jz .socket_type_ok |
449 | jz .socketnum_type_ok |
449 | inc edx ; edx = SOCK_DGRAM |
450 | inc edx ; edx = SOCK_DGRAM |
450 | cmp esi, IPPROTO_UDP |
451 | cmp esi, IPPROTO_UDP |
451 | jz .socket_type_ok |
452 | jz .socketnum_type_ok |
452 | .ret: |
453 | .ret: |
453 | ; Restore saved registers, destroy stack frame and return. |
454 | ; Restore saved registers, destroy stack frame and return. |
454 | mov esp, ebp |
455 | mov esp, ebp |
455 | pop ebp |
456 | pop ebp |
456 | pop edi esi ebx |
457 | pop edi esi ebx |
Line 462... | Line 463... | ||
462 | cmp edx, SOCK_STREAM |
463 | cmp edx, SOCK_STREAM |
463 | jz .check_tcp |
464 | jz .check_tcp |
464 | cmp edx, SOCK_DGRAM |
465 | cmp edx, SOCK_DGRAM |
465 | jnz .ret |
466 | jnz .ret |
466 | test esi, esi |
467 | test esi, esi |
467 | jz .socket_type_ok |
468 | jz .socketnum_type_ok |
468 | cmp esi, IPPROTO_UDP |
469 | cmp esi, IPPROTO_UDP |
469 | jz .socket_type_ok |
470 | jz .socketnum_type_ok |
470 | jmp .ret |
471 | jmp .ret |
471 | .check_tcp: |
472 | .check_tcp: |
472 | test esi, esi |
473 | test esi, esi |
473 | jz .socket_type_ok |
474 | jz .socketnum_type_ok |
474 | cmp esi, IPPROTO_TCP |
475 | cmp esi, IPPROTO_TCP |
475 | jnz .ret |
476 | jnz .ret |
476 | .socket_type_ok: |
477 | .socketnum_type_ok: |
477 | mov [ebx+__gai_reqdata.socktype], dl |
478 | mov [ebx+__gai_reqdata.socktype], dl |
478 | ; 2. Resolve service. |
479 | ; 2. Resolve service. |
479 | ; 2a. If no name is given, remember value -1. |
480 | ; 2a. If no name is given, remember value -1. |
480 | push -1 |
481 | push -1 |
481 | pop edx |
482 | pop edx |
Line 511... | Line 512... | ||
511 | ; 2d. Save result to reqdata. |
512 | ; 2d. Save result to reqdata. |
512 | mov [ebx+__gai_reqdata.service], edx |
513 | mov [ebx+__gai_reqdata.service], edx |
513 | ; 3. Process host name. |
514 | ; 3. Process host name. |
514 | mov esi, [.hostname] |
515 | mov esi, [.hostname] |
515 | ; 3a. If hostname is not given, |
516 | ; 3a. If hostname is not given, |
516 | ; use localhost for active sockets and INADDR_ANY for passive sockets. |
517 | ; use localhost for active socketnums and INADDR_ANY for passive socketnums. |
517 | mov eax, 0x0100007F ; 127.0.0.1 in network byte order |
518 | mov eax, 0x0100007F ; 127.0.0.1 in network byte order |
518 | test byte [ebx+__gai_reqdata.flags], AI_PASSIVE |
519 | test byte [ebx+__gai_reqdata.flags], AI_PASSIVE |
519 | jz @f |
520 | jz @f |
520 | xor eax, eax |
521 | xor eax, eax |
521 | @@: |
522 | @@: |
Line 677... | Line 678... | ||
677 | ; 7. Get DNS server address. |
678 | ; 7. Get DNS server address. |
678 | mcall 75, 0x00000004 ; protocol IP=0, device number=0, function=get DNS address |
679 | mcall 75, 0x00000004 ; protocol IP=0, device number=0, function=get DNS address |
679 | cmp eax, -1 |
680 | cmp eax, -1 |
680 | je .ret.dnserr |
681 | je .ret.dnserr |
681 | mov esi, eax ; put server address to esi |
682 | mov esi, eax ; put server address to esi |
682 | ; 8. Open UDP socket to DNS server, port 53. |
683 | ; 8. Open UDP socketnum to DNS server, port 53. |
683 | ; 8a. Create new socket. |
684 | ; 8a. Create new socketnum. |
684 | mcall 74, 0, AF_INET, IPPROTO_UDP |
685 | mcall 74, 0, AF_INET4, SOCK_DGRAM |
685 | cmp eax, -1 ; error? |
686 | cmp eax, -1 ; error? |
686 | jz .ret.dnserr |
687 | jz .ret.dnserr |
687 | mov ecx, eax ; put socket handle to ecx |
688 | mov ecx, eax ; put socketnum handle to ecx |
688 | ; 8b. Create sockaddr structure on the stack. |
689 | ; 8b. Create sockaddr structure on the stack. |
689 | push 0 |
690 | push 0 |
690 | push 0 ; sin_zero |
691 | push 0 ; sin_zero |
691 | push esi ; sin_addr |
692 | push esi ; sin_addr |
692 | push AF_INET + (53 shl 16) |
693 | push AF_INET4 + (53 shl 16) |
693 | ; sin_family and sin_port in network byte order |
694 | ; sin_family and sin_port in network byte order |
694 | ; 8c. Connect. |
695 | ; 8c. Connect. |
695 | mcall 74, 4, , esp, sizeof.sockaddr_in |
696 | mcall 74, 4, , esp, sizeof.sockaddr_in |
696 | ; 8d. Restore the stack, undo 8b. |
697 | ; 8d. Restore the stack, undo 8b. |
697 | add esp, esi |
698 | add esp, esi |
Line 704... | Line 705... | ||
704 | xor edi, edi |
705 | xor edi, edi |
705 | mcall 74, 6, , esp |
706 | mcall 74, 6, , esp |
706 | cmp eax, -1 |
707 | cmp eax, -1 |
707 | jz .ret.close |
708 | jz .ret.close |
708 | mov eax, [.reqdata] |
709 | mov eax, [.reqdata] |
709 | mov [eax+__gai_reqdata.socket], ecx |
710 | mov [eax+__gai_reqdata.socketnum], ecx |
710 | push -1 |
711 | push -1 |
711 | pop eax ; return status: more processing required |
712 | pop eax ; return status: more processing required |
712 | jmp .ret.dns |
713 | jmp .ret.dns |
713 | .ret.close: |
714 | .ret.close: |
714 | mcall 74, 1 |
715 | mcall 74, 1 |
Line 757... | Line 758... | ||
757 | mov edx, esp ; edx -> buffer for datagram |
758 | mov edx, esp ; edx -> buffer for datagram |
758 | ; 1. Save used registers for __stdcall. |
759 | ; 1. Save used registers for __stdcall. |
759 | push ebx esi edi |
760 | push ebx esi edi |
760 | mov edi, [.reqdata] |
761 | mov edi, [.reqdata] |
761 | ; 2. Read UDP datagram. |
762 | ; 2. Read UDP datagram. |
762 | mov ecx, [edi+__gai_reqdata.socket] |
763 | mov ecx, [edi+__gai_reqdata.socketnum] |
763 | push edi |
764 | push edi |
764 | mcall 74, 7, , , 512, 0 |
765 | mcall 74, 7, , , 512, 0 |
765 | pop edi |
766 | pop edi |
766 | ; 3. Ignore events for other sockets (return if no data read) |
767 | ; 3. Ignore events for other socketnums (return if no data read) |
767 | test eax, eax |
768 | test eax, eax |
768 | jz .ret.more_processing_required |
769 | jz .ret.more_processing_required |
769 | ; 4. Sanity check: discard too short packets. |
770 | ; 4. Sanity check: discard too short packets. |
770 | xchg ecx, eax ; save packet length in ecx |
771 | xchg ecx, eax ; save packet length in ecx |
771 | cmp ecx, 12 |
772 | cmp ecx, 12 |
Line 916... | Line 917... | ||
916 | call freeaddrinfo |
917 | call freeaddrinfo |
917 | and dword [esi], 0 |
918 | and dword [esi], 0 |
918 | @@: |
919 | @@: |
919 | pop eax |
920 | pop eax |
920 | .ret.close: |
921 | .ret.close: |
921 | ; 15. Close socket. |
922 | ; 15. Close socketnum. |
922 | push eax |
923 | push eax |
923 | mov ecx, [.reqdata] |
924 | mov ecx, [.reqdata] |
924 | mov ecx, [ecx+__gai_reqdata.socket] |
925 | mov ecx, [ecx+__gai_reqdata.socketnum] |
925 | mcall 74, 1 |
926 | mcall 74, 1 |
926 | pop eax |
927 | pop eax |
927 | ; 16. Restore used registers, destroy stack frame and return. |
928 | ; 16. Restore used registers, destroy stack frame and return. |
928 | .ret: |
929 | .ret: |
929 | pop edi esi ebx |
930 | pop edi esi ebx |
Line 1168... | Line 1169... | ||
1168 | rep stosd |
1169 | rep stosd |
1169 | pop edi |
1170 | pop edi |
1170 | ; 4. Fill struct addrinfo. |
1171 | ; 4. Fill struct addrinfo. |
1171 | mov eax, [ebx+__gai_reqdata.flags] |
1172 | mov eax, [ebx+__gai_reqdata.flags] |
1172 | mov [edi+addrinfo.ai_flags], eax |
1173 | mov [edi+addrinfo.ai_flags], eax |
1173 | mov byte [edi+addrinfo.ai_family], PF_INET |
1174 | mov byte [edi+addrinfo.ai_family], AF_INET4 |
1174 | mov byte [edi+addrinfo.ai_addrlen], sizeof.sockaddr_in |
1175 | mov byte [edi+addrinfo.ai_addrlen], sizeof.sockaddr_in |
1175 | lea ecx, [edi+sizeof.addrinfo] |
1176 | lea ecx, [edi+sizeof.addrinfo] |
1176 | mov [edi+addrinfo.ai_addr], ecx |
1177 | mov [edi+addrinfo.ai_addr], ecx |
1177 | ; 5. Fill struct sockaddr_in. |
1178 | ; 5. Fill struct sockaddr_in. |
1178 | mov byte [ecx+sockaddr_in.sin_family], PF_INET |
1179 | mov byte [ecx+sockaddr_in.sin_family], AF_INET4 |
1179 | pop eax |
1180 | pop eax |
1180 | mov [ecx+sockaddr_in.sin_addr], eax |
1181 | mov [ecx+sockaddr_in.sin_addr], eax |
1181 | ; 6. Append new item to the list. |
1182 | ; 6. Append new item to the list. |
1182 | mov [esi], edi |
1183 | mov [esi], edi |
1183 | lea esi, [edi+addrinfo.ai_next] |
1184 | lea esi, [edi+addrinfo.ai_next] |
Line 1187... | Line 1188... | ||
1187 | pop eax |
1188 | pop eax |
1188 | xor esi, esi |
1189 | xor esi, esi |
1189 | ret |
1190 | ret |
Line 1190... | Line 1191... | ||
1190 | 1191 | ||
1191 | .set_socktype: |
1192 | .set_socktype: |
1192 | ; Set ai_socktype and ai_protocol fields by given socket type. |
1193 | ; Set ai_socktype and ai_protocol fields by given socketnum type. |
1193 | mov byte [edi+addrinfo.ai_socktype], cl |
1194 | mov byte [edi+addrinfo.ai_socktype], cl |
1194 | dec cl |
1195 | dec cl |
1195 | jnz .set_udp |
1196 | jnz .set_udp |
1196 | .set_tcp: |
1197 | .set_tcp: |
Line 1217... | Line 1218... | ||
1217 | ;;---------------------------------------------------------------------------;; |
1218 | ;;---------------------------------------------------------------------------;; |
1218 | ;> first parameter = pointer to struct __gai_reqdata filled by ..._start ;; |
1219 | ;> first parameter = pointer to struct __gai_reqdata filled by ..._start ;; |
1219 | ;;===========================================================================;; |
1220 | ;;===========================================================================;; |
1220 | ; 0. Save used registers for __stdcall. |
1221 | ; 0. Save used registers for __stdcall. |
1221 | push ebx |
1222 | push ebx |
1222 | ; 1. Allocated resources: only socket, so close it and return. |
1223 | ; 1. Allocated resources: only socketnum, so close it and return. |
1223 | mov eax, [esp+8] |
1224 | mov eax, [esp+8] |
1224 | mov ecx, [eax+__gai_reqdata.socket] |
1225 | mov ecx, [eax+__gai_reqdata.socketnum] |
1225 | mcall 74, 1 |
1226 | mcall 74, 1 |
1226 | ; 2. Restore used registers and return. |
1227 | ; 2. Restore used registers and return. |
1227 | pop ebx |
1228 | pop ebx |
1228 | ret 4 |
1229 | ret 4 |