Rev 1155 | Rev 3601 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 1155 | Rev 3545 | ||
---|---|---|---|
Line 26... | Line 26... | ||
26 | mov [mem.alloc], eax |
26 | mov [mem.alloc], eax |
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 | xor eax, eax |
32 | ret 4 |
32 | ret |
Line 33... | Line 33... | ||
33 | 33 | ||
34 | ;;===========================================================================;; |
34 | ;;===========================================================================;; |
35 | ;; in_addr_t __stdcall inet_addr(__in const char* hostname); ;; |
35 | ;; in_addr_t __stdcall inet_addr(__in const char* hostname); ;; |
36 | inet_addr: ;; |
36 | inet_addr: ;; |
Line 255... | Line 255... | ||
255 | mov word [edi], si |
255 | mov word [edi], si |
256 | add edi, 2 |
256 | add edi, 2 |
257 | ret |
257 | ret |
Line 258... | Line 258... | ||
258 | 258 | ||
259 | struct __gai_reqdata |
259 | struct __gai_reqdata |
260 | socket dd ? |
260 | socketnum dd ? |
261 | ; external code should not look on rest of this structure, |
261 | ; external code should not look on rest of this structure, |
262 | ; it is internal for getaddrinfo_start/process/abort |
262 | ; it is internal for getaddrinfo_start/process/abort |
263 | reqid dw ? ; DNS request ID |
263 | reqid dw ? ; DNS request ID |
264 | socktype db ? ; SOCK_* or 0 for any |
264 | socktype db ? ; SOCK_* or 0 for any |
Line 277... | Line 277... | ||
277 | ;;---------------------------------------------------------------------------;; |
277 | ;;---------------------------------------------------------------------------;; |
278 | ;? Get a list of IP addresses and port numbers for given host and service ;; |
278 | ;? Get a list of IP addresses and port numbers for given host and service ;; |
279 | ;;---------------------------------------------------------------------------;; |
279 | ;;---------------------------------------------------------------------------;; |
280 | ;> first parameter (optional) = host name ;; |
280 | ;> first parameter (optional) = host name ;; |
281 | ;> second parameter (optional) = service name (decimal number for now) ;; |
281 | ;> second parameter (optional) = service name (decimal number for now) ;; |
282 | ;> third parameter (optional) = hints for socket type ;; |
282 | ;> third parameter (optional) = hints for socketnum type ;; |
283 | ;> fourth parameter = pointer to result (head of L1-list) ;; |
283 | ;> fourth parameter = pointer to result (head of L1-list) ;; |
284 | ;;---------------------------------------------------------------------------;; |
284 | ;;---------------------------------------------------------------------------;; |
285 | ;< eax = 0 on success / one of EAI_ codes on error ;; |
285 | ;< eax = 0 on success / one of EAI_ codes on error ;; |
286 | ;;===========================================================================;; |
286 | ;;===========================================================================;; |
287 | ; 0. Save used registers for __stdcall. |
287 | ; 0. Save used registers for __stdcall. |
Line 423... | Line 423... | ||
423 | push EAI_FAMILY |
423 | push EAI_FAMILY |
424 | pop eax |
424 | pop eax |
425 | jecxz @f |
425 | jecxz @f |
426 | cmp [ecx+addrinfo.ai_family], edi |
426 | cmp [ecx+addrinfo.ai_family], edi |
427 | jz @f |
427 | jz @f |
428 | cmp [ecx+addrinfo.ai_family], PF_INET |
428 | cmp [ecx+addrinfo.ai_family], AF_INET4 |
429 | jnz .ret |
429 | jnz .ret |
430 | @@: |
430 | @@: |
431 | ; 1e. Valid combinations for ai_socktype/ai_protocol: 0/0 for any or |
431 | ; 1e. Valid combinations for ai_socktype/ai_protocol: 0/0 for any or |
432 | ; SOCK_STREAM/IPPROTO_TCP, SOCK_DGRAM/IPPROTO_UDP |
432 | ; SOCK_STREAM/IPPROTO_TCP, SOCK_DGRAM/IPPROTO_UDP |
433 | ; (raw sockets are not yet supported by the kernel) |
433 | ; (raw socketnums are not yet supported by the kernel) |
434 | xor edx, edx ; assume 0=any if no hints |
434 | xor edx, edx ; assume 0=any if no hints |
435 | jecxz .socket_type_ok |
435 | jecxz .socketnum_type_ok |
436 | mov edx, [ecx+addrinfo.ai_socktype] |
436 | mov edx, [ecx+addrinfo.ai_socktype] |
437 | mov esi, [ecx+addrinfo.ai_protocol] |
437 | mov esi, [ecx+addrinfo.ai_protocol] |
438 | ; 1f. Test for ai_socktype=0 and ai_protocol=0. |
438 | ; 1f. Test for ai_socktype=0 and ai_protocol=0. |
439 | test edx, edx |
439 | test edx, edx |
440 | jnz .check_socktype |
440 | jnz .check_socktype |
441 | test esi, esi |
441 | test esi, esi |
442 | jz .socket_type_ok |
442 | jz .socketnum_type_ok |
443 | ; 1g. ai_socktype=0, ai_protocol is nonzero. |
443 | ; 1g. ai_socktype=0, ai_protocol is nonzero. |
444 | push EAI_SERVICE |
444 | push EAI_SERVICE |
445 | pop eax |
445 | pop eax |
446 | inc edx ; edx = SOCK_STREAM |
446 | inc edx ; edx = SOCK_STREAM |
447 | cmp esi, IPPROTO_TCP |
447 | cmp esi, IPPROTO_TCP |
448 | jz .socket_type_ok |
448 | jz .socketnum_type_ok |
449 | inc edx ; edx = SOCK_DGRAM |
449 | inc edx ; edx = SOCK_DGRAM |
450 | cmp esi, IPPROTO_UDP |
450 | cmp esi, IPPROTO_UDP |
451 | jz .socket_type_ok |
451 | jz .socketnum_type_ok |
452 | .ret: |
452 | .ret: |
453 | ; Restore saved registers, destroy stack frame and return. |
453 | ; Restore saved registers, destroy stack frame and return. |
454 | mov esp, ebp |
454 | mov esp, ebp |
455 | pop ebp |
455 | pop ebp |
456 | pop edi esi ebx |
456 | pop edi esi ebx |
Line 462... | Line 462... | ||
462 | cmp edx, SOCK_STREAM |
462 | cmp edx, SOCK_STREAM |
463 | jz .check_tcp |
463 | jz .check_tcp |
464 | cmp edx, SOCK_DGRAM |
464 | cmp edx, SOCK_DGRAM |
465 | jnz .ret |
465 | jnz .ret |
466 | test esi, esi |
466 | test esi, esi |
467 | jz .socket_type_ok |
467 | jz .socketnum_type_ok |
468 | cmp esi, IPPROTO_UDP |
468 | cmp esi, IPPROTO_UDP |
469 | jz .socket_type_ok |
469 | jz .socketnum_type_ok |
470 | jmp .ret |
470 | jmp .ret |
471 | .check_tcp: |
471 | .check_tcp: |
472 | test esi, esi |
472 | test esi, esi |
473 | jz .socket_type_ok |
473 | jz .socketnum_type_ok |
474 | cmp esi, IPPROTO_TCP |
474 | cmp esi, IPPROTO_TCP |
475 | jnz .ret |
475 | jnz .ret |
476 | .socket_type_ok: |
476 | .socketnum_type_ok: |
477 | mov [ebx+__gai_reqdata.socktype], dl |
477 | mov [ebx+__gai_reqdata.socktype], dl |
478 | ; 2. Resolve service. |
478 | ; 2. Resolve service. |
479 | ; 2a. If no name is given, remember value -1. |
479 | ; 2a. If no name is given, remember value -1. |
480 | push -1 |
480 | push -1 |
481 | pop edx |
481 | pop edx |
Line 511... | Line 511... | ||
511 | ; 2d. Save result to reqdata. |
511 | ; 2d. Save result to reqdata. |
512 | mov [ebx+__gai_reqdata.service], edx |
512 | mov [ebx+__gai_reqdata.service], edx |
513 | ; 3. Process host name. |
513 | ; 3. Process host name. |
514 | mov esi, [.hostname] |
514 | mov esi, [.hostname] |
515 | ; 3a. If hostname is not given, |
515 | ; 3a. If hostname is not given, |
516 | ; use localhost for active sockets and INADDR_ANY for passive sockets. |
516 | ; use localhost for active socketnums and INADDR_ANY for passive socketnums. |
517 | mov eax, 0x0100007F ; 127.0.0.1 in network byte order |
517 | mov eax, 0x0100007F ; 127.0.0.1 in network byte order |
518 | test byte [ebx+__gai_reqdata.flags], AI_PASSIVE |
518 | test byte [ebx+__gai_reqdata.flags], AI_PASSIVE |
519 | jz @f |
519 | jz @f |
520 | xor eax, eax |
520 | xor eax, eax |
521 | @@: |
521 | @@: |
Line 673... | Line 673... | ||
673 | ; query class = IN (internet IPv4 address) = 1 |
673 | ; query class = IN (internet IPv4 address) = 1 |
674 | ; Note that network byte order is big-endian. |
674 | ; Note that network byte order is big-endian. |
675 | mov eax, 0x01000100 |
675 | mov eax, 0x01000100 |
676 | stosd |
676 | stosd |
677 | ; 7. Get DNS server address. |
677 | ; 7. Get DNS server address. |
- | 678 | mcall 76, API_IPv4 + 4 ; protocol IP=0, device number=0, function=get DNS address |
|
678 | mcall 52, 13 |
679 | cmp eax, -1 |
- | 680 | je .ret.dnserr |
|
679 | xchg esi, eax ; put server address to esi |
681 | mov esi, eax ; put server address to esi |
680 | ; 8. Open UDP socket to DNS server, port 53. |
682 | ; 8. Open UDP socketnum to DNS server, port 53. |
- | 683 | ; 8a. Create new socketnum. |
|
681 | mcall 53, 0, 0, 53 |
684 | mcall 75, 0, AF_INET4, SOCK_DGRAM |
682 | cmp eax, -1 ; error? |
685 | cmp eax, -1 ; error? |
683 | jz .ret.dnserr |
686 | jz .ret.dnserr |
684 | xchg ecx, eax ; put socket handle to ecx |
687 | mov ecx, eax ; put socketnum handle to ecx |
- | 688 | ; 8b. Create sockaddr structure on the stack. |
|
- | 689 | push 0 |
|
- | 690 | push 0 ; sin_zero |
|
- | 691 | push esi ; sin_addr |
|
- | 692 | push AF_INET4 + (53 shl 24) |
|
- | 693 | ; sin_family and sin_port in network byte order |
|
- | 694 | ; 8c. Connect. |
|
- | 695 | mcall 75, 4, , esp, sizeof.sockaddr_in |
|
- | 696 | ; 8d. Restore the stack, undo 8b. |
|
- | 697 | add esp, esi |
|
- | 698 | ; 8e. Check result. |
|
- | 699 | cmp eax, -1 |
|
- | 700 | jz .ret.close |
|
685 | ; 9. Send DNS request packet. |
701 | ; 9. Send DNS request packet. |
686 | sub edi, esp ; get packet length |
702 | sub edi, esp ; get packet length |
- | 703 | mov esi, edi |
|
687 | mcall 53, 4, , edi, esp |
704 | xor edi, edi |
- | 705 | mcall 75, 6, , esp |
|
688 | cmp eax, -1 |
706 | cmp eax, -1 |
689 | jz .ret.close |
707 | jz .ret.close |
690 | mov eax, [.reqdata] |
708 | mov eax, [.reqdata] |
691 | mov [eax+__gai_reqdata.socket], ecx |
709 | mov [eax+__gai_reqdata.socketnum], ecx |
692 | push -1 |
710 | push -1 |
693 | pop eax ; return status: more processing required |
711 | pop eax ; return status: more processing required |
694 | jmp .ret.dns |
712 | jmp .ret.dns |
695 | .ret.close: |
713 | .ret.close: |
696 | mcall 53, 1 |
714 | mcall 75, 1 |
697 | .ret.dnserr: |
715 | .ret.dnserr: |
698 | push EAI_AGAIN |
716 | push EAI_AGAIN |
699 | pop eax |
717 | pop eax |
700 | .ret.dns: |
718 | .ret.dns: |
701 | ; 6. Restore stack pointer and return. |
719 | ; 6. Restore stack pointer and return. |
Line 739... | Line 757... | ||
739 | mov edx, esp ; edx -> buffer for datagram |
757 | mov edx, esp ; edx -> buffer for datagram |
740 | ; 1. Save used registers for __stdcall. |
758 | ; 1. Save used registers for __stdcall. |
741 | push ebx esi edi |
759 | push ebx esi edi |
742 | mov edi, [.reqdata] |
760 | mov edi, [.reqdata] |
743 | ; 2. Read UDP datagram. |
761 | ; 2. Read UDP datagram. |
744 | mov ecx, [edi+__gai_reqdata.socket] |
762 | mov ecx, [edi+__gai_reqdata.socketnum] |
- | 763 | push edi |
|
745 | mcall 53, 11, , , 512 |
764 | mcall 75, 7, , , 512, 0 |
- | 765 | pop edi |
|
746 | ; 3. Ignore events for other sockets (return if no data read) |
766 | ; 3. Ignore events for other socketnums (return if no data read) |
747 | test eax, eax |
767 | test eax, eax |
748 | jz .ret.more_processing_required |
768 | jz .ret.more_processing_required |
749 | ; 4. Sanity check: discard too short packets. |
769 | ; 4. Sanity check: discard too short packets. |
750 | xchg ecx, eax ; save packet length in ecx |
770 | xchg ecx, eax ; save packet length in ecx |
751 | cmp ecx, 12 |
771 | cmp ecx, 12 |
Line 896... | Line 916... | ||
896 | call freeaddrinfo |
916 | call freeaddrinfo |
897 | and dword [esi], 0 |
917 | and dword [esi], 0 |
898 | @@: |
918 | @@: |
899 | pop eax |
919 | pop eax |
900 | .ret.close: |
920 | .ret.close: |
901 | ; 15. Close socket. |
921 | ; 15. Close socketnum. |
902 | push eax |
922 | push eax |
903 | mov ecx, [.reqdata] |
923 | mov ecx, [.reqdata] |
904 | mov ecx, [ecx+__gai_reqdata.socket] |
924 | mov ecx, [ecx+__gai_reqdata.socketnum] |
905 | mcall 53, 1 |
925 | mcall 75, 1 |
906 | pop eax |
926 | pop eax |
907 | ; 16. Restore used registers, destroy stack frame and return. |
927 | ; 16. Restore used registers, destroy stack frame and return. |
908 | .ret: |
928 | .ret: |
909 | pop edi esi ebx |
929 | pop edi esi ebx |
910 | mov esp, ebp |
930 | mov esp, ebp |
Line 1148... | Line 1168... | ||
1148 | rep stosd |
1168 | rep stosd |
1149 | pop edi |
1169 | pop edi |
1150 | ; 4. Fill struct addrinfo. |
1170 | ; 4. Fill struct addrinfo. |
1151 | mov eax, [ebx+__gai_reqdata.flags] |
1171 | mov eax, [ebx+__gai_reqdata.flags] |
1152 | mov [edi+addrinfo.ai_flags], eax |
1172 | mov [edi+addrinfo.ai_flags], eax |
1153 | mov byte [edi+addrinfo.ai_family], PF_INET |
1173 | mov byte [edi+addrinfo.ai_family], AF_INET4 |
1154 | mov byte [edi+addrinfo.ai_addrlen], sizeof.sockaddr_in |
1174 | mov byte [edi+addrinfo.ai_addrlen], sizeof.sockaddr_in |
1155 | lea ecx, [edi+sizeof.addrinfo] |
1175 | lea ecx, [edi+sizeof.addrinfo] |
1156 | mov [edi+addrinfo.ai_addr], ecx |
1176 | mov [edi+addrinfo.ai_addr], ecx |
1157 | ; 5. Fill struct sockaddr_in. |
1177 | ; 5. Fill struct sockaddr_in. |
1158 | mov byte [ecx+sockaddr_in.sin_len], sizeof.sockaddr_in |
- | |
1159 | mov byte [ecx+sockaddr_in.sin_family], PF_INET |
1178 | mov byte [ecx+sockaddr_in.sin_family], AF_INET4 |
1160 | pop eax |
1179 | pop eax |
1161 | mov [ecx+sockaddr_in.sin_addr], eax |
1180 | mov [ecx+sockaddr_in.sin_addr], eax |
1162 | ; 6. Append new item to the list. |
1181 | ; 6. Append new item to the list. |
1163 | mov [esi], edi |
1182 | mov [esi], edi |
1164 | lea esi, [edi+addrinfo.ai_next] |
1183 | lea esi, [edi+addrinfo.ai_next] |
Line 1168... | Line 1187... | ||
1168 | pop eax |
1187 | pop eax |
1169 | xor esi, esi |
1188 | xor esi, esi |
1170 | ret |
1189 | ret |
Line 1171... | Line 1190... | ||
1171 | 1190 | ||
1172 | .set_socktype: |
1191 | .set_socktype: |
1173 | ; Set ai_socktype and ai_protocol fields by given socket type. |
1192 | ; Set ai_socktype and ai_protocol fields by given socketnum type. |
1174 | mov byte [edi+addrinfo.ai_socktype], cl |
1193 | mov byte [edi+addrinfo.ai_socktype], cl |
1175 | dec cl |
1194 | dec cl |
1176 | jnz .set_udp |
1195 | jnz .set_udp |
1177 | .set_tcp: |
1196 | .set_tcp: |
Line 1183... | Line 1202... | ||
1183 | 1202 | ||
1184 | .set_port: |
1203 | .set_port: |
1185 | ; Just copy port from input __gai_reqdata to output addrinfo. |
1204 | ; Just copy port from input __gai_reqdata to output addrinfo. |
1186 | push edx |
1205 | push edx |
1187 | mov edx, [ebx+__gai_reqdata.service] |
1206 | mov edx, [ebx+__gai_reqdata.service] |
1188 | xchg dl, dh ; convert to network byte order |
1207 | xchg dl, dh ; convert to network byte order ;;;;; CHECKME |
1189 | mov [edi+sizeof.addrinfo+sockaddr_in.sin_port], dx |
1208 | mov [edi+sizeof.addrinfo+sockaddr_in.sin_port], dx |
1190 | pop edx |
1209 | pop edx |
Line 1191... | Line 1210... | ||
1191 | ret |
1210 | ret |
Line 1198... | Line 1217... | ||
1198 | ;;---------------------------------------------------------------------------;; |
1217 | ;;---------------------------------------------------------------------------;; |
1199 | ;> first parameter = pointer to struct __gai_reqdata filled by ..._start ;; |
1218 | ;> first parameter = pointer to struct __gai_reqdata filled by ..._start ;; |
1200 | ;;===========================================================================;; |
1219 | ;;===========================================================================;; |
1201 | ; 0. Save used registers for __stdcall. |
1220 | ; 0. Save used registers for __stdcall. |
1202 | push ebx |
1221 | push ebx |
1203 | ; 1. Allocated resources: only socket, so close it and return. |
1222 | ; 1. Allocated resources: only socketnum, so close it and return. |
1204 | mov eax, [esp+8] |
1223 | mov eax, [esp+8] |
1205 | mov ecx, [eax+__gai_reqdata.socket] |
1224 | mov ecx, [eax+__gai_reqdata.socketnum] |
1206 | mcall 53, 1 |
1225 | mcall 75, 1 |
1207 | ; 2. Restore used registers and return. |
1226 | ; 2. Restore used registers and return. |
1208 | pop ebx |
1227 | pop ebx |
1209 | ret 4 |
1228 | ret 4 |
Line 1210... | Line 1229... | ||
1210 | 1229 | ||
Line 1262... | Line 1281... | ||
1262 | getaddrinfo_start , 'getaddrinfo_start' , \ |
1281 | getaddrinfo_start , 'getaddrinfo_start' , \ |
1263 | getaddrinfo_process , 'getaddrinfo_process' , \ |
1282 | getaddrinfo_process , 'getaddrinfo_process' , \ |
1264 | getaddrinfo_abort , 'getaddrinfo_abort' , \ |
1283 | getaddrinfo_abort , 'getaddrinfo_abort' , \ |
1265 | freeaddrinfo , 'freeaddrinfo' |
1284 | freeaddrinfo , 'freeaddrinfo' |
Line 1266... | Line -... | ||
1266 | - | ||
1267 | ; import from libini |
- | |
1268 | align 4 |
- | |
1269 | @IMPORT: |
- | |
1270 | - | ||
1271 | library libini, 'libini.obj' |
- | |
1272 | import libini, \ |
- | |
1273 | ini.get_str, 'ini_get_str', \ |
- | |
1274 | ini.get_int, 'ini_get_int' |
- | |
1275 | - | ||
1276 | 1285 | ||
1277 | section '.data' data readable writable align 16 |
1286 | section '.data' data readable writable align 16 |
1278 | ; uninitialized data |
1287 | ; uninitialized data |
1279 | mem.alloc dd ? |
1288 | mem.alloc dd ? |
1280 | mem.free dd ? |
1289 | mem.free dd ? |