Subversion Repositories Kolibri OS

Rev

Rev 1318 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
1159 hidnplayr 1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2
;;                                                                 ;;
1196 hidnplayr 3
;; Copyright (C) KolibriOS team 2004-2009. All rights reserved.    ;;
1159 hidnplayr 4
;; Distributed under terms of the GNU General Public License       ;;
5
;;                                                                 ;;
6
;;  SOCKET.INC                                                     ;;
7
;;                                                                 ;;
8
;;    Written by hidnplayr@kolibrios.org                           ;;
9
;;    based on code by mike.dld                                    ;;
10
;;                                                                 ;;
11
;;          GNU GENERAL PUBLIC LICENSE                             ;;
12
;;             Version 2, June 1991                                ;;
13
;;                                                                 ;;
14
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
15
 
1206 hidnplayr 16
$Revision: 1335 $
1159 hidnplayr 17
 
1249 hidnplayr 18
struct	SOCKET_head
1159 hidnplayr 19
	 .PrevPtr		dd ? ; pointer to previous socket in list
20
	 .NextPtr		dd ? ; pointer to next socket in list
21
	 .Number		dd ? ; socket number (unique within single process)
22
	 .PID			dd ? ; application process id
23
	 .Domain		dd ? ; INET/UNIX/..
24
	 .Type			dd ? ; RAW/UDP/TCP/...
1196 hidnplayr 25
	 .Protocol		dd ? ; ICMP/IPv4/ARP/
1249 hidnplayr 26
	 .lock			dd ? ; lock mutex
1318 hidnplayr 27
	 .errorcode		dd ?
1249 hidnplayr 28
	 .end:
29
ends
30
 
31
struct	IPv4_SOCKET
32
	 .LocalIP		dd ?
33
	 .RemoteIP		dd ?
34
	 .SequenceNumber	dd ?
35
 
36
	; todo: add options (for func 8 and 9)
37
 
38
	 .end:
39
ends
40
 
41
struct	TCP_SOCKET
42
 
43
	 .LocalPort		dw ? ; In INET byte order
44
	 .RemotePort		dw ? ; In INET byte order
45
 
46
	 .backlog		dw ? ; Backlog
1256 clevermous 47
	 .backlog_cur		dw ? ; current size of queue for un-accept-ed connections
48
	 .last_ack_number	dd ? ; used only to let application know that ACK has been received
49
					; todo: may be use SND_UNA instead
50
					; todo: may be use events which allow additional information instead
51
					; todo: may be count acknowledged bytes (at least it has obvious sense)
1274 hidnplayr 52
	 .OrigRemoteIP		dd ? ; original remote IP address (used to reset to LISTEN state)
53
	 .OrigRemotePort	dw ? ; original remote port (used to reset to LISTEN state)
1254 hidnplayr 54
	 .wndsizeTimer		dd ? ; window size timer
55
 
56
	; Transmission control block
57
	 .state 		dd ? ; TCB state
58
	 .timer 		dd ? ; TCB timer (seconds)
1318 hidnplayr 59
 
1254 hidnplayr 60
	 .ISS			dd ? ; initial send sequence number
61
	 .IRS			dd ? ; initial receive sequence number
1196 hidnplayr 62
	 .SND_UNA		dd ? ; sequence number of unack'ed sent Packets
1249 hidnplayr 63
	 .SND_NXT		dd ? ; next send sequence number to use
1196 hidnplayr 64
	 .SND_WND		dd ? ; send window
65
	 .RCV_NXT		dd ? ; next receive sequence number to use
66
	 .RCV_WND		dd ? ; receive window
67
	 .SEG_LEN		dd ? ; segment length
68
	 .SEG_WND		dd ? ; segment window
1249 hidnplayr 69
 
70
	 .flags 		db ? ; packet flags
71
 
72
	 .end:
1159 hidnplayr 73
ends
74
 
1249 hidnplayr 75
struct	UDP_SOCKET
1159 hidnplayr 76
 
1249 hidnplayr 77
	 .LocalPort		dw ? ; In INET byte order
78
	 .RemotePort		dw ? ; In INET byte order
1335 hidnplayr 79
	 .firstpacket		db ?
1159 hidnplayr 80
 
1249 hidnplayr 81
	 .end:
82
ends
83
 
84
struct	ICMP_SOCKET
85
 
86
	.Identifier		dw ? ;
87
 
88
	.end:
89
 
90
ends
91
 
92
struct	IPC_SOCKET
93
 
94
	.ConnectedTo		dd ? ; Socket number of other socket this one is connected to
95
 
96
	.end:
97
 
98
ends
99
 
1274 hidnplayr 100
struct	socket_queue_entry
101
	.data_ptr	dd ?
102
	.data_size	dd ?
103
	.offset 	dd ?
104
	.size:
105
ends
106
 
1249 hidnplayr 107
MAX_backlog		equ 20	     ; backlog for stream sockets
108
SOCKETBUFFSIZE		equ 4096     ; in bytes
109
SOCKET_QUEUE_SIZE	equ 10	     ; maximum number ofincoming packets queued for 1 socket
1257 hidnplayr 110
SOCKET_QUEUE_LOCATION	equ 2048     ; the incoming packet queue for sockets is placed in the socket struct itself, at this location from start
1249 hidnplayr 111
 
1159 hidnplayr 112
uglobal
113
	net_sockets	rd 2
114
	last_UDP_port	dw ? ; These values give the number of the last used ephemeral port
115
	last_TCP_port	dw ? ;
116
endg
117
 
118
 
1257 hidnplayr 119
;-----------------------------------------------------------------
1159 hidnplayr 120
;
121
; SOCKET_init
122
;
123
;  -
124
;
125
;  IN:  /
126
;  OUT: /
127
;
1257 hidnplayr 128
;-----------------------------------------------------------------
1159 hidnplayr 129
align 4
130
socket_init:
131
 
132
	mov	[net_sockets], 0
133
	mov	[net_sockets + 4], 0
134
 
135
	mov	[last_UDP_port], MIN_EPHEMERAL_PORT
136
	mov	[last_TCP_port], MIN_EPHEMERAL_PORT
137
 
138
	ret
139
 
140
 
1257 hidnplayr 141
;-----------------------------------------------------------------
1159 hidnplayr 142
;
143
; Socket API (function 74)
144
;
1257 hidnplayr 145
;-----------------------------------------------------------------
1159 hidnplayr 146
align 4
147
sys_socket:
1254 hidnplayr 148
	and	ebx, 0x000000FF ; should i remove this line ?
1256 clevermous 149
	cmp	bl , 8		; highest possible number
1254 hidnplayr 150
	jg	s_error
151
	lea	ebx, [.table + 4*ebx]
152
	jmp	dword [ebx]
1159 hidnplayr 153
 
1254 hidnplayr 154
.table:
155
	dd	socket_open	; 0
156
	dd	socket_close	; 1
157
	dd	socket_bind	; 2
158
	dd	socket_listen	; 3
159
	dd	socket_connect	; 4
160
	dd	socket_accept	; 5
161
	dd	socket_send	; 6
162
	dd	socket_recv	; 7
1257 hidnplayr 163
	dd	socket_get_opt	; 8
1254 hidnplayr 164
;        dd      socket_set_opt  ; 9
1159 hidnplayr 165
 
1254 hidnplayr 166
 
1185 hidnplayr 167
s_error:
1159 hidnplayr 168
	mov	dword [esp+32],-1
169
 
170
	ret
171
 
172
 
1257 hidnplayr 173
;-----------------------------------------------------------------
1159 hidnplayr 174
;
175
; SOCKET_open
176
;
177
;
178
;  IN:  domain in ecx
179
;       type in edx
1196 hidnplayr 180
;       protocol in esi
1159 hidnplayr 181
;  OUT: eax is socket num, -1 on error
182
;
1257 hidnplayr 183
;-----------------------------------------------------------------
1206 hidnplayr 184
align 4
1159 hidnplayr 185
socket_open:
186
 
187
	DEBUGF	1,"socket_open: domain: %u, type: %u",ecx, edx
188
 
189
	call	net_socket_alloc
190
	or	eax, eax
1185 hidnplayr 191
	jz	s_error
1159 hidnplayr 192
 
1249 hidnplayr 193
	mov	[eax + SOCKET_head.Domain], ecx
194
	mov	[eax + SOCKET_head.Type], edx
195
	mov	[eax + SOCKET_head.Protocol], esi
1159 hidnplayr 196
 
1318 hidnplayr 197
	cmp	ecx, AF_INET4
198
	je	.af_inet4
199
 
200
	jmp	.done
201
 
202
 
203
  .af_inet4:
204
 
205
	cmp	edx, IP_PROTO_TCP
206
	je	.tcp
207
 
208
	jmp	.done
209
 
210
  .tcp:
211
 
212
	mov	[eax + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.state], TCB_CLOSED
213
 
214
	pseudo_random ebx
215
	mov	[eax + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.ISS], ebx
216
	mov	[eax + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.SND_NXT], ebx
217
 
218
  .done:
1159 hidnplayr 219
	stdcall net_socket_addr_to_num, eax
220
	DEBUGF	1,", socketnumber: %u\n", eax
221
 
222
	mov	[esp+32], eax
223
 
224
	ret
225
 
226
 
227
 
1257 hidnplayr 228
;-----------------------------------------------------------------
1159 hidnplayr 229
;
230
; SOCKET_bind
231
;
232
;  IN:  socket number in ecx
233
;       pointer to sockaddr struct in edx
234
;       length of that struct in esi
235
;  OUT: 0 on success
236
;
1257 hidnplayr 237
;-----------------------------------------------------------------
1206 hidnplayr 238
align 4
1159 hidnplayr 239
socket_bind:
240
 
241
	DEBUGF	1,"Socket_bind: socknum: %u sockaddr: %x, length: %u, ",ecx,edx,esi
242
 
243
	stdcall net_socket_num_to_addr, ecx
244
	cmp	eax, -1
1185 hidnplayr 245
	jz	s_error
1159 hidnplayr 246
 
247
	cmp	esi, 2
1185 hidnplayr 248
	jl	s_error
1159 hidnplayr 249
 
250
	cmp	word [edx], AF_INET4
1249 hidnplayr 251
	je	.af_inet4
1159 hidnplayr 252
 
1249 hidnplayr 253
	cmp	word [edx], AF_UNIX
254
	je	.af_unix
255
 
256
	jmp	s_error
257
 
258
  .af_unix:
259
 
260
	; TODO: write code here
261
 
262
	mov	dword [esp+32],0
263
	ret
264
 
1159 hidnplayr 265
  .af_inet4:
266
 
267
	cmp	esi, 6
1185 hidnplayr 268
	jl	s_error
1159 hidnplayr 269
 
1249 hidnplayr 270
	mov	ecx, [eax + SOCKET_head.Type]
271
 
1159 hidnplayr 272
	mov	bx, word [edx + 2]
1206 hidnplayr 273
	DEBUGF	1,"local port: %x ",bx
1159 hidnplayr 274
	test	bx, bx
1206 hidnplayr 275
	jz	.find_free
1159 hidnplayr 276
 
1206 hidnplayr 277
	call	socket_check_port
278
	test	bx, bx
279
	je	s_error
280
	jmp	.got_port
1159 hidnplayr 281
 
1249 hidnplayr 282
    .find_free:
1159 hidnplayr 283
 
1206 hidnplayr 284
	call	socket_find_port
285
	test	bx, bx
286
	je	s_error
1159 hidnplayr 287
 
1249 hidnplayr 288
    .got_port:
1206 hidnplayr 289
	DEBUGF	1,"using port: %x ",bx
1249 hidnplayr 290
	mov	word [eax + SOCKET_head.end + IPv4_SOCKET.end + UDP_SOCKET.LocalPort], bx
1159 hidnplayr 291
 
292
	mov	ebx, dword [edx + 4]
1249 hidnplayr 293
	mov	dword [eax + SOCKET_head.end + IPv4_SOCKET.LocalIP], ebx
1159 hidnplayr 294
 
295
	DEBUGF	1,"local ip: %u.%u.%u.%u\n",\
1249 hidnplayr 296
	[eax + SOCKET_head.end + IPv4_SOCKET.LocalIP + 0]:1,[eax + SOCKET_head.end + IPv4_SOCKET.LocalIP + 1]:1,\
297
	[eax + SOCKET_head.end + IPv4_SOCKET.LocalIP + 2]:1,[eax + SOCKET_head.end + IPv4_SOCKET.LocalIP + 3]:1
1159 hidnplayr 298
 
299
	mov	dword [esp+32],0
300
	ret
301
 
302
 
303
 
304
 
1257 hidnplayr 305
;-----------------------------------------------------------------
1159 hidnplayr 306
;
307
; SOCKET_connect
308
;
309
;
310
;  IN:  socket number in ecx
311
;       pointer to sockaddr struct in edx
312
;       length of that struct in esi
313
;  OUT: 0 on success
314
;
1257 hidnplayr 315
;-----------------------------------------------------------------
1159 hidnplayr 316
align 4
317
socket_connect:
318
 
319
	DEBUGF	1,"Socket_connect: socknum: %u sockaddr: %x, length: %u,",ecx,edx,esi
320
 
321
	stdcall net_socket_num_to_addr, ecx
322
	cmp	eax, -1
1185 hidnplayr 323
	jz	s_error
1159 hidnplayr 324
 
1254 hidnplayr 325
	cmp	esi, 8
1185 hidnplayr 326
	jl	s_error
1159 hidnplayr 327
 
328
	cmp	word [edx], AF_INET4
329
	je	.af_inet4
330
 
1185 hidnplayr 331
	jmp	s_error
1159 hidnplayr 332
 
333
  .af_inet4:
334
 
1249 hidnplayr 335
	cmp	[eax + SOCKET_head.Type], IP_PROTO_UDP
1159 hidnplayr 336
	je	.udp
337
 
1249 hidnplayr 338
	cmp	[eax + SOCKET_head.Type], IP_PROTO_TCP
1206 hidnplayr 339
	je	.tcp
1159 hidnplayr 340
 
1185 hidnplayr 341
	jmp	s_error
1159 hidnplayr 342
 
1254 hidnplayr 343
  .udp:
1159 hidnplayr 344
 
345
	mov	bx , word [edx + 2]
1249 hidnplayr 346
	mov	word [eax + SOCKET_head.end + IPv4_SOCKET.end + UDP_SOCKET.RemotePort], bx
1335 hidnplayr 347
	mov	[eax + SOCKET_head.end + IPv4_SOCKET.end + UDP_SOCKET.firstpacket], 0
1206 hidnplayr 348
	DEBUGF	1,"remote port: %x ",bx
1159 hidnplayr 349
 
350
	mov	ebx, dword [edx + 4]
1249 hidnplayr 351
	mov	dword [eax + SOCKET_head.end + IPv4_SOCKET.RemoteIP], ebx
1159 hidnplayr 352
	DEBUGF	1,"remote ip: %u.%u.%u.%u\n",[edx+4]:1,[edx+5]:1,[edx+6]:1,[edx+7]:1
353
 
354
	mov	dword [esp+32],0
355
	ret
356
 
357
 
1254 hidnplayr 358
  .tcp:
359
	; TODO: set sequence number to random value
1159 hidnplayr 360
 
1281 hidnplayr 361
	lea	ebx, [eax + SOCKET_head.lock]
362
	call	wait_mutex
1159 hidnplayr 363
 
1254 hidnplayr 364
	; fill in remote port and IP
1159 hidnplayr 365
 
1254 hidnplayr 366
	mov	[eax + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.wndsizeTimer], 0	   ; Reset the window timer.
367
											   ; TODO: figure out WTF this is
368
	mov	bx , word [edx + 2]
369
	mov	[eax + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.RemotePort], bx
370
	DEBUGF	1,"remote port: %x ",bx
1159 hidnplayr 371
 
1254 hidnplayr 372
	mov	ebx, dword [edx + 4]
373
	mov	[eax + SOCKET_head.end + IPv4_SOCKET.RemoteIP], ebx
1159 hidnplayr 374
 
1254 hidnplayr 375
	; check if local port and IP is ok
1159 hidnplayr 376
 
1254 hidnplayr 377
	cmp	[eax + SOCKET_head.end + IPv4_SOCKET.LocalIP], 0
378
	jne	@f
379
	push	[IP_LIST]	    ; device zero = default
380
	pop	[eax + SOCKET_head.end + IPv4_SOCKET.LocalIP]
381
       @@:
1159 hidnplayr 382
 
1254 hidnplayr 383
	cmp	[eax + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.LocalPort], 0
384
	jne	@f
1159 hidnplayr 385
 
1254 hidnplayr 386
	mov	ecx, [eax + SOCKET_head.Type]
387
	call	socket_find_port
388
	test	bx, bx
389
	jz	s_error
1159 hidnplayr 390
 
1254 hidnplayr 391
	mov	[eax + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.LocalPort], bx
392
       @@:
1159 hidnplayr 393
 
394
 
1254 hidnplayr 395
	mov	[eax + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.state], TCB_SYN_SENT
396
	; now say hello to the remote tcp socket
1159 hidnplayr 397
 
1254 hidnplayr 398
	mov	bl, TH_SYN
1274 hidnplayr 399
	xor	ecx, ecx
400
	call	TCP_send
1159 hidnplayr 401
 
1254 hidnplayr 402
	mov	dword [esp+32],0
1159 hidnplayr 403
	ret
404
 
405
 
1257 hidnplayr 406
;-----------------------------------------------------------------
1159 hidnplayr 407
;
408
; SOCKET_listen
409
;
410
;
411
;  IN:  socket number in ecx
412
;       backlog in edx
413
;  OUT: eax is socket num, -1 on error
414
;
1257 hidnplayr 415
;-----------------------------------------------------------------
1206 hidnplayr 416
align 4
1159 hidnplayr 417
socket_listen:
418
 
419
	DEBUGF	1,"Socket_listen: socknum: %u backlog: %u\n",ecx,edx
420
 
421
	stdcall net_socket_num_to_addr, ecx
422
	cmp	eax, -1
1185 hidnplayr 423
	jz	s_error
1159 hidnplayr 424
 
1254 hidnplayr 425
	cmp	word [eax + SOCKET_head.Domain], AF_INET4
426
	jne	s_error
427
 
428
	cmp	[eax + SOCKET_head.Type], IP_PROTO_TCP
429
	jne	s_error
430
 
1159 hidnplayr 431
	cmp	edx, MAX_backlog
1256 clevermous 432
	jb	.ok
433
	mov	dx , MAX_backlog
1159 hidnplayr 434
  .ok:
435
 
1249 hidnplayr 436
	mov	[eax + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.backlog], dx
1254 hidnplayr 437
	mov	[eax + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.state], TCB_LISTEN
1159 hidnplayr 438
 
439
	mov	dword [esp+32], 0
440
	ret
441
 
442
 
1257 hidnplayr 443
;-----------------------------------------------------------------
1159 hidnplayr 444
;
445
; SOCKET_accept
446
;
447
;
448
;  IN:  socket number in ecx
449
;       addr in edx
450
;       addrlen in esi
451
;  OUT: eax is socket num, -1 on error
452
;
1257 hidnplayr 453
;-----------------------------------------------------------------
1206 hidnplayr 454
align 4
1159 hidnplayr 455
socket_accept:
456
 
457
	DEBUGF	1,"Socket_accept: socknum: %u sockaddr: %x, length: %u\n",ecx,edx,esi
458
 
459
	stdcall net_socket_num_to_addr, ecx
460
	or	eax, eax
1185 hidnplayr 461
	jz	s_error
1159 hidnplayr 462
	mov	esi, eax
463
 
1249 hidnplayr 464
	cmp	word [esi + SOCKET_head.Domain], AF_INET4
465
	je	.af_inet4
466
 
467
	jmp	s_error
468
 
469
  .af_inet4:
470
 
471
	cmp	[esi + SOCKET_head.Type], IP_PROTO_TCP
472
	je	.tcp
473
 
474
	jmp	s_error
475
 
476
  .tcp:
477
 
1256 clevermous 478
	lea	ebx, [esi + SOCKET_head.lock]
479
	call	wait_mutex
480
	movzx	eax, [esi + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.backlog_cur]
481
	test	eax, eax
482
	jz	.unlock_err
483
	dec	[esi + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.backlog_cur]
484
	mov	eax, [eax + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.end + (eax-1)*4]
485
	mov	[esi + SOCKET_head.lock], 0
1257 hidnplayr 486
	stdcall net_socket_addr_to_num, eax
1159 hidnplayr 487
	mov	[esp+32], eax
488
	ret
1256 clevermous 489
  .unlock_err:
490
	mov	[esi + SOCKET_head.lock], 0
491
	jmp	s_error
1159 hidnplayr 492
 
493
 
1257 hidnplayr 494
;-----------------------------------------------------------------
1159 hidnplayr 495
;
496
; SOCKET_close
497
;
498
;
499
;  IN:  socket number in ecx
500
;  OUT: eax is socket num, -1 on error
501
;
1257 hidnplayr 502
;-----------------------------------------------------------------
1206 hidnplayr 503
align 4
1159 hidnplayr 504
socket_close:
505
 
506
	DEBUGF	1,"Socket_close: socknum: %u\n",ecx
507
 
508
	stdcall net_socket_num_to_addr, ecx
509
	or	eax, eax
1185 hidnplayr 510
	jz	s_error
1159 hidnplayr 511
 
1249 hidnplayr 512
	cmp	[eax + SOCKET_head.Domain], AF_INET4
513
	jne	s_error
1159 hidnplayr 514
 
1249 hidnplayr 515
	cmp	[eax + SOCKET_head.Type], IP_PROTO_UDP
1159 hidnplayr 516
	je	.udp
517
 
1249 hidnplayr 518
	cmp	[eax + SOCKET_head.Type], IP_PROTO_ICMP
1159 hidnplayr 519
	je	.icmp
520
 
1249 hidnplayr 521
	cmp	[eax + SOCKET_head.Type], IP_PROTO_TCP
1206 hidnplayr 522
	je	.tcp
1159 hidnplayr 523
 
1185 hidnplayr 524
	jmp	s_error
1159 hidnplayr 525
 
526
  .udp:
527
 
528
	stdcall net_socket_free, eax
529
	mov	dword [esp+32],0
530
	ret
531
 
532
 
533
  .icmp:
534
 
535
 
536
 
537
	ret
538
 
539
  .tcp:
1318 hidnplayr 540
	mov	dword [esp+32],0
541
 
1254 hidnplayr 542
	; first, remove all resend entries for this socket
1159 hidnplayr 543
 
1318 hidnplayr 544
	call	TCP_remove_socket
1159 hidnplayr 545
 
1318 hidnplayr 546
;        cmp     [eax + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.state], TCB_LISTEN
547
;        je      .destroy_tcb
548
;        cmp     [eax + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.state], TCB_SYN_SENT
549
;        je      .destroy_tcb
550
;        cmp     [eac + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.state], TCB_CLOSED
551
;        je      .destroy_tcb
552
	cmp	[eax + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.state], TCB_SYN_RECEIVED
553
	je	.fin_wait
554
	cmp	[eax + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.state], TCB_ESTABLISHED
555
	je	.fin_wait
556
	cmp	[eax + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.state], TCB_CLOSE_WAIT
557
	je	.last_ack
1159 hidnplayr 558
 
1318 hidnplayr 559
	stdcall net_socket_free, ebx
1159 hidnplayr 560
 
1318 hidnplayr 561
	ret
1159 hidnplayr 562
 
563
 
1318 hidnplayr 564
  .last_ack:
565
	mov	[eax + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.state], TCB_LAST_ACK
566
	jmp	.send_fin
1159 hidnplayr 567
 
1318 hidnplayr 568
  .fin_wait:
569
	mov	[eax + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.state], TCB_FIN_WAIT_1
570
 
571
  .send_fin:
572
	mov	bl, TH_FIN + TH_ACK
573
	xor	ecx, ecx
574
	call	TCP_send
575
 
1159 hidnplayr 576
	ret
577
 
578
 
579
 
580
 
1257 hidnplayr 581
;-----------------------------------------------------------------
1159 hidnplayr 582
;
583
; SOCKET_receive
584
;
585
;
586
;  IN:  socket number in ecx
1249 hidnplayr 587
;       addr to buffer in edx
588
;       length of buffer in esi
1159 hidnplayr 589
;       flags in edi
590
;  OUT: eax is number of bytes copied, -1 on error
591
;
1257 hidnplayr 592
;-----------------------------------------------------------------
1206 hidnplayr 593
align 4
1159 hidnplayr 594
socket_recv:
595
 
1281 hidnplayr 596
	DEBUGF	1,"Socket_receive: socknum: %u bufaddr: %x, buflength: %u, flags: %x\n",ecx,edx,esi,edi
1159 hidnplayr 597
	stdcall net_socket_num_to_addr, ecx		   ; get real socket address
598
	or	eax, eax
1185 hidnplayr 599
	jz	s_error
1159 hidnplayr 600
 
1281 hidnplayr 601
	mov	ebx, esi
602
 
1249 hidnplayr 603
	DEBUGF	1,"Socket pointer: %x\n", eax
1159 hidnplayr 604
 
1281 hidnplayr 605
	get_from_queue (eax + SOCKET_QUEUE_LOCATION), SOCKET_QUEUE_SIZE, socket_queue_entry.size, s_error	; destroys esi and ecx
1159 hidnplayr 606
 
1281 hidnplayr 607
	mov	edi, edx					; addr to buffer
1249 hidnplayr 608
	mov	ecx, [esi + socket_queue_entry.data_size]
1159 hidnplayr 609
 
1249 hidnplayr 610
	DEBUGF	1,"Got %u bytes of data\n", ecx
1159 hidnplayr 611
 
1281 hidnplayr 612
	cmp	ecx, ebx
1249 hidnplayr 613
	jle	.large_enough
614
	DEBUGF	1,"Buffer too small...\n"
615
	jmp	s_error
616
  .large_enough:
1159 hidnplayr 617
 
1281 hidnplayr 618
	push	[esi + socket_queue_entry.data_ptr]		; save the buffer addr so we can clear it later
1249 hidnplayr 619
	mov	esi, [esi + socket_queue_entry.offset]
1281 hidnplayr 620
	add	esi, [esp]					; calculate the real data offset
1249 hidnplayr 621
	DEBUGF	1,"Source buffer: %x, real addr: %x\n", [esp], esi
1159 hidnplayr 622
 
1281 hidnplayr 623
	mov	dword[esp+32+4], ecx				; return number of bytes copied
1159 hidnplayr 624
 
1249 hidnplayr 625
	shr	ecx, 1
626
	jnc	.nb
627
	movsb
628
.nb:	shr	ecx, 1
629
	jnc	.nw
630
	movsw
1274 hidnplayr 631
.nw:	test	ecx, ecx
632
	jz	.nd
633
	rep	movsd
634
.nd:
1159 hidnplayr 635
 
1281 hidnplayr 636
	call	kernel_free					; todo: check if ALL applications had the chance to receive data
1159 hidnplayr 637
 
638
	ret
639
 
640
 
1257 hidnplayr 641
;-----------------------------------------------------------------
1159 hidnplayr 642
;
643
; SOCKET_send
644
;
645
;
646
;  IN:  socket number in ecx
1206 hidnplayr 647
;       pointer to data in edx
648
;       datalength in esi
1159 hidnplayr 649
;       flags in edi
650
;  OUT: -1 on error
651
;
1257 hidnplayr 652
;-----------------------------------------------------------------
1206 hidnplayr 653
align 4
1159 hidnplayr 654
socket_send:
655
 
656
	DEBUGF	1,"Socket_send: socknum: %u sockaddr: %x, length: %u, flags: %x, ",ecx,edx,esi,edi
657
 
658
	stdcall net_socket_num_to_addr, ecx		   ; get real socket address
659
	or	eax, eax
1185 hidnplayr 660
	jz	s_error
1159 hidnplayr 661
 
1249 hidnplayr 662
	cmp	word [eax + SOCKET_head.Domain], AF_INET4
1206 hidnplayr 663
	je	.af_inet4
664
 
665
	jmp	s_error
666
 
667
  .af_inet4:
1249 hidnplayr 668
	DEBUGF	1,"Socket type:%u\n", [eax + SOCKET_head.Type]:4
1206 hidnplayr 669
 
1249 hidnplayr 670
	cmp	[eax + SOCKET_head.Type], IP_PROTO_TCP
671
	je	.tcp
1159 hidnplayr 672
 
1249 hidnplayr 673
	cmp	[eax + SOCKET_head.Type], IP_PROTO_UDP
1159 hidnplayr 674
	je	.udp
675
 
1249 hidnplayr 676
	cmp	[eax + SOCKET_head.Type], SOCK_RAW
677
	je	.raw
1159 hidnplayr 678
 
1185 hidnplayr 679
	jmp	s_error
1159 hidnplayr 680
 
681
  .udp:
682
 
1206 hidnplayr 683
	DEBUGF	1,"type: UDP, "
1159 hidnplayr 684
 
1249 hidnplayr 685
	cmp	[eax + SOCKET_head.end + IPv4_SOCKET.end + UDP_SOCKET.LocalPort],0
686
	jne	@f
1206 hidnplayr 687
 
1208 hidnplayr 688
	push	esi
1249 hidnplayr 689
	mov	ecx, [eax + SOCKET_head.Type]
1206 hidnplayr 690
	call	socket_find_port
691
	test	bx, bx
1208 hidnplayr 692
	pop	esi
1206 hidnplayr 693
	je	s_error
1249 hidnplayr 694
	mov	[eax + SOCKET_head.end + IPv4_SOCKET.end + UDP_SOCKET.LocalPort], bx
1206 hidnplayr 695
 
1249 hidnplayr 696
     @@:
1206 hidnplayr 697
 
1159 hidnplayr 698
	mov	ecx, esi
699
	mov	esi, edx
700
 
1249 hidnplayr 701
	call	UDP_socket_send
1159 hidnplayr 702
 
1263 clevermous 703
	and	dword [esp+32], 0
1159 hidnplayr 704
	ret
705
 
1249 hidnplayr 706
  .tcp:
1159 hidnplayr 707
 
1254 hidnplayr 708
	cmp	[eax + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.LocalPort],0
709
	jne	@f
710
 
711
	push	esi
712
	mov	ecx, [eax + SOCKET_head.Type]
713
	call	socket_find_port
714
	test	bx, bx
715
	pop	esi
716
	je	s_error
717
	mov	[eax + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.LocalPort], bx
718
 
719
     @@:
720
 
721
	mov	ecx, esi
722
	mov	esi, edx
1281 hidnplayr 723
	mov	bl, TH_PUSH + TH_ACK
1254 hidnplayr 724
 
1274 hidnplayr 725
	call	TCP_send
1254 hidnplayr 726
 
1249 hidnplayr 727
	mov	[esp+32], eax
728
	ret
1159 hidnplayr 729
 
1249 hidnplayr 730
  .raw:
731
	cmp	[eax + SOCKET_head.Protocol], IP_PROTO_IP
732
	je	.raw_ip
733
 
734
	cmp	[eax + SOCKET_head.Protocol], IP_PROTO_ICMP
735
	je	.raw_icmp
736
 
737
	jmp	s_error
738
 
739
 
740
  .raw_ip:
741
 
1254 hidnplayr 742
	;;;;;;
743
 
1159 hidnplayr 744
	mov	[esp+32], eax
745
	ret
746
 
747
 
1249 hidnplayr 748
  .raw_icmp:
749
 
750
;        sub     ecx, ICMP_Packet.Data
751
;        mov     esi, edx
752
;        push    ax
753
;        call    IPv4_get_frgmnt_num
754
;        mov     dx, ax
755
;        pop     ax
756
;        shl     edx, 16
757
;        mov     dh , [esi + ICMP_Packet.Type]
758
;        mov     dl , [esi + ICMP_Packet.Code]
759
;        mov     di , [esi + ICMP_Packet.Identifier]
760
;        mov     [eax + SOCKET.LocalPort], di            ; Set localport to the identifier number, so we can receive reply's
761
;        shl     edi, 16
762
;        mov     di , [esi + ICMP_Packet.SequenceNumber]
763
;        add     esi, ICMP_Packet.Data
764
;        mov     ebx, [eax + SOCKET.LocalIP]
765
;        mov     eax, [eax + SOCKET.RemoteIP]
766
;        call    ICMP_create_packet
767
 
768
	mov	[esp+32], eax
1159 hidnplayr 769
	ret
770
 
1257 hidnplayr 771
;-----------------------------------------------------------------
1256 clevermous 772
;
1257 hidnplayr 773
; SOCKET_get_options
1256 clevermous 774
;
775
;
776
;  IN:  socket number in ecx
777
;       edx points to the options:
1257 hidnplayr 778
;               dd      level, optname, optval, optlen
1256 clevermous 779
;  OUT: -1 on error
780
;
781
; At moment, uses only pseudo-optname -2 for get last_ack_number for TCP.
782
; TODO: find best way to notify that send()'ed data were acknowledged
1299 clevermous 783
; Also pseudo-optname -3 is valid and returns socket state, one of TCB_*.
1256 clevermous 784
;
1257 hidnplayr 785
;-----------------------------------------------------------------
786
align 4
1256 clevermous 787
socket_get_opt:
1257 hidnplayr 788
 
1256 clevermous 789
	cmp	dword [edx], IP_PROTO_TCP
790
	jnz	.unknown
791
	cmp	dword [edx+4], -2
1299 clevermous 792
	jz	@f
793
	cmp	dword [edx+4], -3
1256 clevermous 794
	jnz	.unknown
1299 clevermous 795
@@:
1256 clevermous 796
	mov	eax, [edx+12]
797
	test	eax, eax
798
	jz	.fail
799
	cmp	dword [eax], 4
800
	mov	dword [eax], 4
801
	jb	.fail
1257 hidnplayr 802
	stdcall net_socket_num_to_addr, ecx
1256 clevermous 803
	test	eax, eax
804
	jz	.fail
805
	; todo: check that eax is really TCP socket
806
	mov	ecx, [eax + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.last_ack_number]
1299 clevermous 807
	cmp	dword [edx+4], -2
808
	jz	@f
809
	mov	ecx, [eax + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.state]
810
@@:
1256 clevermous 811
	mov	eax, [edx+8]
812
	test	eax, eax
813
	jz	@f
814
	mov	[eax], ecx
815
@@:
1257 hidnplayr 816
	mov	dword [esp+32], 0
1256 clevermous 817
	ret
818
.fail:
819
.unknown:
1257 hidnplayr 820
	mov	dword [esp+32], -1
1256 clevermous 821
	ret
1159 hidnplayr 822
 
823
 
1257 hidnplayr 824
;-----------------------------------------------------------------
1206 hidnplayr 825
;
826
; SOCKET_find_free_port (local port)
827
;
828
; works with INET byte order
829
;
830
;  IN:  type in ecx (TCP/UDP)
831
;  OUT: bx = 0 on error, portnumber otherwise
832
;
1257 hidnplayr 833
;-----------------------------------------------------------------
1206 hidnplayr 834
align 4
835
socket_find_port:
1159 hidnplayr 836
 
1208 hidnplayr 837
	DEBUGF	1,"Socket_find_free_port\n"
1159 hidnplayr 838
 
1206 hidnplayr 839
	cmp	ecx, IP_PROTO_UDP
840
	je	.udp
1159 hidnplayr 841
 
1206 hidnplayr 842
	cmp	ecx, IP_PROTO_TCP
843
	je	.tcp
1159 hidnplayr 844
 
1206 hidnplayr 845
  .udp:
846
	mov	bx, [last_UDP_port]
847
	je	.continue
848
 
849
  .tcp:
850
	mov	bx, [last_TCP_port]
851
 
852
 
853
  .continue:
854
	inc	bx
855
 
856
  .check_only:
857
	mov	esi, net_sockets
858
 
859
  .next_socket:
1249 hidnplayr 860
	mov	esi, [esi + SOCKET_head.NextPtr]
1206 hidnplayr 861
	or	esi, esi
862
	jz	.port_ok
863
 
1249 hidnplayr 864
	cmp	[esi + SOCKET_head.Type], ecx
1206 hidnplayr 865
	jne	.next_socket
866
 
867
	rol	bx, 8
1249 hidnplayr 868
	cmp	[esi + SOCKET_head.end + IPv4_SOCKET.end + UDP_SOCKET.LocalPort], bx
1206 hidnplayr 869
	rol	bx, 8				; this doesnt change the zero flag, does it ?
870
	jne	.next_socket
871
 
872
	cmp	bx, MAX_EPHEMERAL_PORT
873
	jle	.continue
874
 
875
	; todo: WRAP!
876
;        mov     [last_UDP_port], MIN_EPHEMERAL_PORT
877
  .exit:
878
	xor	ebx, ebx
879
 
880
  .port_ok:
881
	rol	bx, 8
882
	ret
883
 
1257 hidnplayr 884
 
885
 
886
;-----------------------------------------------------------------
1206 hidnplayr 887
;
888
; SOCKET_check_port (local port)
889
;
890
; works with INET byte order
891
;
892
;  IN:  type in ecx (TCP/UDP)
893
;       port to check in bx
894
;  OUT: bx = 0 on error, unchanged otherwise
895
;
1257 hidnplayr 896
;-----------------------------------------------------------------
1206 hidnplayr 897
align 4
898
socket_check_port:
899
	mov	esi, net_sockets
900
 
901
  .next_socket:
1249 hidnplayr 902
	mov	esi, [esi + SOCKET_head.NextPtr]
1206 hidnplayr 903
	or	esi, esi
904
	jz	.port_ok
905
 
1249 hidnplayr 906
	cmp	[esi + SOCKET_head.Type], ecx
1206 hidnplayr 907
	jne	.next_socket
908
 
1249 hidnplayr 909
	cmp	[esi + SOCKET_head.end + IPv4_SOCKET.end + UDP_SOCKET.LocalPort], bx
1206 hidnplayr 910
	jne	.next_socket
911
 
912
	xor	ebx, ebx
913
 
914
  .port_ok:
915
	ret
916
 
917
 
1257 hidnplayr 918
 
919
;-----------------------------------------------------------------
1206 hidnplayr 920
;
921
; SOCKET_internal_receiver
922
;
1249 hidnplayr 923
; Updates a socket with received data
1206 hidnplayr 924
;
1249 hidnplayr 925
; Note: the mutex must already be set !
1206 hidnplayr 926
;
1249 hidnplayr 927
;  IN:  eax = socket ptr
928
;       ecx = size
929
;       esi = pointer to buffer
930
;       edi = offset
931
;
1206 hidnplayr 932
;  OUT: xxx
933
;
1257 hidnplayr 934
;-----------------------------------------------------------------
1206 hidnplayr 935
align 4
936
socket_internal_receiver:
937
 
1255 hidnplayr 938
	DEBUGF 1,"Internal socket receiver: buffer %x, offset: %x size=%u socket: %x\n", esi, edi, ecx, eax
1206 hidnplayr 939
 
1249 hidnplayr 940
	push	edi	; offset
941
	push	ecx	; size
942
	push	esi	; data_ptr
943
	mov	esi, esp
1257 hidnplayr 944
	add_to_queue (eax + SOCKET_QUEUE_LOCATION), SOCKET_QUEUE_SIZE, socket_queue_entry.size, notify_network_event.full
1249 hidnplayr 945
	DEBUGF	1,"Queued packet successfully\n"
1257 hidnplayr 946
	add	esp, socket_queue_entry.size
1206 hidnplayr 947
 
1249 hidnplayr 948
	mov	[eax + SOCKET_head.lock], 0
1206 hidnplayr 949
 
1256 clevermous 950
notify_network_event:
1206 hidnplayr 951
	; flag an event to the application
1249 hidnplayr 952
	mov	edx, [eax + SOCKET_head.PID]				; get socket owner PID
1206 hidnplayr 953
	mov	ecx, 1
954
	mov	esi, TASK_DATA + TASKDATA.pid
955
 
956
       .next_pid:
957
	cmp	[esi], edx
958
	je	.found_pid
959
	inc	ecx
960
	add	esi, 0x20
961
	cmp	ecx, [TASK_COUNT]
962
	jbe	.next_pid
963
	ret
964
 
965
       .found_pid:
966
	shl	ecx, 8
1249 hidnplayr 967
	or	[ecx + SLOT_BASE + APPDATA.event_mask], EVENT_NETWORK	; stack event
1206 hidnplayr 968
	mov	[check_idle_semaphore], 200
969
	ret
970
 
1249 hidnplayr 971
  .full:
972
	DEBUGF 1,"Socket %x is full!\n",eax
973
	mov	[eax + SOCKET_head.lock], 0
974
	call	kernel_free
975
	add	esp, 8
1206 hidnplayr 976
	ret
977
 
978
 
979
 
1159 hidnplayr 980
; Allocate memory for socket data and put new socket into the list
981
; Newly created socket is initialized with calling PID and number and
982
; put into beginning of list (which is a fastest way).
983
;
984
; @return socket structure address in EAX
985
;
986
proc net_socket_alloc stdcall uses ebx ecx edx edi
987
	stdcall kernel_alloc, SOCKETBUFFSIZE
988
	DEBUGF	1, "K : net_socket_alloc (0x%x)\n", eax
989
	; check if we can allocate needed amount of memory
990
	or	eax, eax
991
	jz	.exit
992
 
993
	; zero-initialize allocated memory
994
	push	eax
995
	mov	edi, eax
1249 hidnplayr 996
 
1159 hidnplayr 997
	mov	ecx, SOCKETBUFFSIZE / 4
998
;        cld
999
	xor	eax, eax
1000
	rep	stosd
1001
	pop	eax
1002
 
1257 hidnplayr 1003
	init_queue (eax + SOCKET_QUEUE_LOCATION)
1249 hidnplayr 1004
 
1159 hidnplayr 1005
	; add socket to the list by changing pointers
1006
	mov	ebx, net_sockets
1249 hidnplayr 1007
	push	[ebx + SOCKET_head.NextPtr]
1008
	mov	[ebx + SOCKET_head.NextPtr], eax
1009
	mov	[eax + SOCKET_head.PrevPtr], ebx
1159 hidnplayr 1010
	pop	ebx
1249 hidnplayr 1011
	mov	[eax + SOCKET_head.NextPtr], ebx
1159 hidnplayr 1012
	or	ebx, ebx
1013
	jz	@f
1249 hidnplayr 1014
	mov	[ebx + SOCKET_head.PrevPtr], eax
1159 hidnplayr 1015
 
1016
    @@: ; set socket owner PID to the one of calling process
1017
	mov	ebx, [TASK_BASE]
1018
	mov	ebx, [ebx + TASKDATA.pid]
1249 hidnplayr 1019
	mov	[eax + SOCKET_head.PID], ebx
1159 hidnplayr 1020
 
1021
	; find first free socket number and use it
1022
	;mov     edx, ebx
1023
	mov	ebx, net_sockets
1024
	xor	ecx, ecx
1025
  .next_socket_number:
1026
	inc	ecx
1027
  .next_socket:
1249 hidnplayr 1028
	mov	ebx, [ebx + SOCKET_head.NextPtr]
1159 hidnplayr 1029
	or	ebx, ebx
1030
	jz	.last_socket_number
1249 hidnplayr 1031
	cmp	[ebx + SOCKET_head.Number], ecx
1159 hidnplayr 1032
	jne	.next_socket
1033
	;cmp     [ebx + SOCKET.PID], edx
1034
	;jne     .next_socket
1035
	mov	ebx, net_sockets
1036
	jmp	.next_socket_number
1037
 
1038
  .last_socket_number:
1249 hidnplayr 1039
	mov	[eax + SOCKET_head.Number], ecx
1159 hidnplayr 1040
 
1041
  .exit:
1042
	ret
1043
endp
1044
 
1045
; Free socket data memory and pop socket off the list
1046
;
1047
; @param sockAddr is a socket structure address
1048
;
1049
proc net_socket_free stdcall uses ebx ecx edx, sockAddr:DWORD
1050
	mov	eax, [sockAddr]
1051
	DEBUGF	1, "K : net_socket_free (0x%x)\n", eax
1052
	; check if we got something similar to socket structure address
1053
	or	eax, eax
1054
	jz	.error
1055
 
1056
	; make sure sockAddr is one of the socket addresses in the list
1057
	mov	ebx, net_sockets
1058
	;mov     ecx, [TASK_BASE]
1059
	;mov     ecx, [ecx + TASKDATA.pid]
1060
  .next_socket:
1249 hidnplayr 1061
	mov	ebx, [ebx + SOCKET_head.NextPtr]
1159 hidnplayr 1062
	or	ebx, ebx
1063
	jz	.error
1064
	cmp	ebx, eax
1065
	jne	.next_socket
1066
	;cmp     [ebx + SOCKET.PID], ecx
1067
	;jne     .next_socket
1068
 
1069
	; okay, we found the correct one
1070
	; remove it from the list first, changing pointers
1249 hidnplayr 1071
	mov	ebx, [eax + SOCKET_head.NextPtr]
1072
	mov	eax, [eax + SOCKET_head.PrevPtr]
1073
	mov	[eax + SOCKET_head.NextPtr], ebx
1159 hidnplayr 1074
	or	ebx, ebx
1075
	jz	@f
1249 hidnplayr 1076
	mov	[ebx + SOCKET_head.PrevPtr], eax
1159 hidnplayr 1077
 
1249 hidnplayr 1078
	lea	ebx, [eax + SOCKET_head.lock]
1079
	call	wait_mutex
1080
 
1159 hidnplayr 1081
    @@: ; and finally free the memory structure used
1082
	stdcall kernel_free, [sockAddr]
1083
	ret
1084
 
1085
  .error:
1086
	DEBUGF	1, "K :   failed\n"
1087
	ret
1088
endp
1089
 
1090
; Get socket structure address by its number
1091
; Scan through sockets list to find the socket with specified number.
1092
; This proc uses SOCKET.PID indirectly to check if socket is owned by
1093
; calling process.
1094
;
1095
; @param sockNum is a socket number
1096
; @return socket structure address or 0 (not found) in EAX
1097
;
1098
proc net_socket_num_to_addr stdcall uses ebx ecx, sockNum:DWORD
1099
	mov	eax, [sockNum]
1100
	; check if we got something similar to socket number
1101
	or	eax, eax
1102
	jz	.error
1103
 
1104
	; scan through sockets list
1105
	mov	ebx, net_sockets
1106
	;mov     ecx, [TASK_BASE]
1107
	;mov     ecx, [ecx + TASKDATA.pid]
1108
  .next_socket:
1249 hidnplayr 1109
	mov	ebx, [ebx + SOCKET_head.NextPtr]
1159 hidnplayr 1110
	or	ebx, ebx
1111
	jz	.error
1249 hidnplayr 1112
	cmp	[ebx + SOCKET_head.Number], eax
1159 hidnplayr 1113
	jne	.next_socket
1114
	;cmp     [ebx + SOCKET.PID], ecx
1115
	;jne     .next_socket
1116
 
1117
	; okay, we found the correct one
1118
	mov	eax, ebx
1119
	ret
1120
 
1121
  .error:
1122
	xor	eax, eax
1123
	ret
1124
endp
1125
 
1126
; Get socket number by its structure address
1127
; Scan through sockets list to find the socket with specified address.
1128
; This proc uses SOCKET.PID indirectly to check if socket is owned by
1129
; calling process.
1130
;
1131
; @param sockAddr is a socket structure address
1132
; @return socket number (SOCKET.Number) or 0 (not found) in EAX
1133
;
1134
proc net_socket_addr_to_num stdcall uses ebx ecx, sockAddr:DWORD
1135
	mov	eax, [sockAddr]
1136
	; check if we got something similar to socket structure address
1137
	or	eax, eax
1138
	jz	.error
1139
 
1140
	; scan through sockets list
1141
	mov	ebx, net_sockets
1142
	;mov     ecx, [TASK_BASE]
1143
	;mov     ecx, [ecx + TASKDATA.pid]
1144
  .next_socket:
1249 hidnplayr 1145
	mov	ebx, [ebx + SOCKET_head.NextPtr]
1159 hidnplayr 1146
	or	ebx, ebx
1147
	jz	.error
1148
	cmp	ebx, eax
1149
	jne	.next_socket
1150
	;cmp     [ebx + SOCKET.PID], ecx
1151
	;jne     .next_socket
1152
 
1153
	; okay, we found the correct one
1249 hidnplayr 1154
	mov	eax, [ebx + SOCKET_head.Number]
1159 hidnplayr 1155
	ret
1156
 
1157
  .error:
1158
	xor	eax, eax
1159
	ret
1160
endp