Subversion Repositories Kolibri OS

Rev

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