Subversion Repositories Kolibri OS

Rev

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