Subversion Repositories Kolibri OS

Rev

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

Rev Author Line No. Line
1159 hidnplayr 1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2
;;                                                                 ;;
1514 hidnplayr 3
;; Copyright (C) KolibriOS team 2004-2010. 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                           ;;
1514 hidnplayr 9
;;     based on code by mike.dld                                   ;;
1159 hidnplayr 10
;;                                                                 ;;
11
;;          GNU GENERAL PUBLIC LICENSE                             ;;
12
;;             Version 2, June 1991                                ;;
13
;;                                                                 ;;
14
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
15
 
1206 hidnplayr 16
$Revision: 1519 $
1159 hidnplayr 17
 
1514 hidnplayr 18
virtual at 0
1249 hidnplayr 19
 
1514 hidnplayr 20
	SOCKET:
21
	.NextPtr		dd ? ; pointer to next socket in list
22
	.PrevPtr		dd ? ; pointer to previous socket in list
23
	.Number 		dd ? ; socket number
1249 hidnplayr 24
 
1514 hidnplayr 25
	.lock			dd ? ; lock mutex
1249 hidnplayr 26
 
1514 hidnplayr 27
	.PID			dd ? ; application process id
28
	.Domain 		dd ? ; INET/UNIX/..
29
	.Type			dd ? ; RAW/UDP/TCP/...
30
	.Protocol		dd ? ; ICMP/IPv4/ARP/
31
	.errorcode		dd ?
1249 hidnplayr 32
 
1514 hidnplayr 33
	.options		dd ?
34
	.SO_SND.SB_CC		dd ?  ;;;;; socket options: number of bytes in socket
35
	.SO_RCV.SB_CC		dd ?
36
	.state			dd ?  ;;;;;;;;;
1249 hidnplayr 37
 
1514 hidnplayr 38
	.end:
39
end virtual
1249 hidnplayr 40
 
1514 hidnplayr 41
virtual at SOCKET.end
1254 hidnplayr 42
 
1514 hidnplayr 43
	IP_SOCKET:
1318 hidnplayr 44
 
1514 hidnplayr 45
	.LocalIP		dd ?
46
				rd 3 ; for IPv6 addresses
1249 hidnplayr 47
 
1514 hidnplayr 48
	.RemoteIP		dd ?
49
				rd 3 ; for IPv6 addresses
1249 hidnplayr 50
 
1514 hidnplayr 51
	.end:
52
end virtual
1159 hidnplayr 53
 
1514 hidnplayr 54
virtual at SOCKET.end
1159 hidnplayr 55
 
1514 hidnplayr 56
	SOCKET_virtual:
1159 hidnplayr 57
 
1514 hidnplayr 58
	.ConnectedTo		dd ? ; Socket number of other socket this one is connected to
1249 hidnplayr 59
 
1514 hidnplayr 60
	.end:
61
end virtual
1249 hidnplayr 62
 
1514 hidnplayr 63
virtual at IP_SOCKET.end
1249 hidnplayr 64
 
1514 hidnplayr 65
	TCP_SOCKET:
66
 
67
	.LocalPort		dw ? ; In INET byte order
68
	.RemotePort		dw ? ; In INET byte order
69
 
70
	.backlog		dw ? ; Backlog
71
	.backlog_cur		dw ? ; current size of queue for un-accept-ed connections
72
 
73
	.OrigRemoteIP		dd ? ; original remote IP address (used to reset to LISTEN state)
74
	.OrigRemotePort 	dw ? ; original remote port (used to reset to LISTEN state)
75
 
76
	.t_state		dd ? ; TCB state
77
	.t_rxtshift		dd ?
78
	.t_rxtcur		dd ?
79
	.t_dupacks		dd ?
80
	.t_maxseg		dd ?
81
	.t_force		dd ?
82
	.t_flags		dd ?
83
 
84
;---------------
85
; RFC783 page 21
86
 
87
; send sequence
88
	.SND_UNA		dd ? ; sequence number of unack'ed sent Packets
89
	.SND_NXT		dd ? ; next send sequence number to use
90
	.SND_UP 		dd ?
91
	.SND_WL1		dd ? ; window minus one
92
	.SND_WL2		dd ? ;
93
	.ISS			dd ? ; initial send sequence number
94
	.SND_WND		dd ? ; send window
95
 
96
; receive sequence
97
	.RCV_WND		dw ? ; receive window
98
	.RCV_NXT		dd ? ; next receive sequence number to use
99
	.RCV_UP 		dd ?
100
	.IRS			dd ? ; initial receive sequence number
101
 
102
;---------------------
103
; Additional variables
104
 
105
; receive variables
106
	.RCV_ADV		dd ?
107
 
108
; retransmit variables
109
	.SND_MAX		dd ?
110
 
111
; congestion control
112
	.SND_CWND		dd ?
113
	.SND_SSTHRESH		dd ?
114
 
115
;----------------------
116
; Transmit timing stuff
117
 
118
	.t_idle 		dd ?
119
	.t_rtt			dd ?
120
	.t_rtseq		dd ?
121
	.t_srtt 		dd ?
122
	.t_rttvar		dd ?
123
	.t_rttmin		dd ?
124
	.max_sndwnd		dd ?
125
 
126
;-----------------
127
; Out-of-band data
128
 
129
	.t_oobflags		dd ?
130
	.t_iobc 		dd ?
131
	.t_softerror		dd ?
132
 
133
 
134
;---------
135
; RFC 1323
136
 
137
	.SND_SCALE		db ? ; Scale factor
138
	.RCV_SCALE		db ?
139
	.request_r_scale	db ?
140
	.requested_s_scale	dd ?
141
 
142
	.ts_recent		dd ?
143
	.ts_recent_age		dd ?
144
	.last_ack_sent		dd ?
145
 
1519 hidnplayr 146
 
147
;-------
148
; Timers
149
 
150
	.timer_retransmission	dw ?	; rexmt
151
	.timer_ack		dw ?
152
	.timer_persist		dw ?
153
	.timer_keepalive	dw ?	; keepalive/syn timeout
154
	.timer_timed_wait	dw ?	; also used as 2msl timer
155
 
1249 hidnplayr 156
	.end:
1514 hidnplayr 157
end virtual
1249 hidnplayr 158
 
1514 hidnplayr 159
virtual at IP_SOCKET.end
1249 hidnplayr 160
 
1514 hidnplayr 161
	UDP_SOCKET:
1249 hidnplayr 162
 
1514 hidnplayr 163
	.LocalPort		dw ? ; In INET byte order
164
	.RemotePort		dw ? ; In INET byte order
165
	.firstpacket		db ?
1249 hidnplayr 166
 
167
	.end:
1514 hidnplayr 168
end virtual
1249 hidnplayr 169
 
1514 hidnplayr 170
virtual at IP_SOCKET.end
1249 hidnplayr 171
 
1514 hidnplayr 172
	ICMP_SOCKET:
173
 
174
	.Identifier		dw ? ;
175
 
176
	.end:
177
end virtual
178
 
179
 
1274 hidnplayr 180
struct	socket_queue_entry
1514 hidnplayr 181
;        .owner          dd ?
1274 hidnplayr 182
	.data_ptr	dd ?
1514 hidnplayr 183
	.buf_ptr	dd ?
1274 hidnplayr 184
	.data_size	dd ?
185
	.size:
186
ends
187
 
1514 hidnplayr 188
 
1249 hidnplayr 189
MAX_backlog		equ 20	     ; backlog for stream sockets
190
SOCKETBUFFSIZE		equ 4096     ; in bytes
1514 hidnplayr 191
 
1249 hidnplayr 192
SOCKET_QUEUE_SIZE	equ 10	     ; maximum number ofincoming packets queued for 1 socket
1514 hidnplayr 193
; the incoming packet queue for sockets is placed in the socket struct itself, at this location from start
194
SOCKET_QUEUE_LOCATION	equ SOCKETBUFFSIZE - SOCKET_QUEUE_SIZE*socket_queue_entry.size - queue.data
1249 hidnplayr 195
 
1159 hidnplayr 196
uglobal
1514 hidnplayr 197
	net_sockets	rd 4
1159 hidnplayr 198
	last_UDP_port	dw ? ; These values give the number of the last used ephemeral port
199
	last_TCP_port	dw ? ;
200
endg
201
 
202
 
1257 hidnplayr 203
;-----------------------------------------------------------------
1159 hidnplayr 204
;
205
; SOCKET_init
206
;
207
;  -
208
;
209
;  IN:  /
210
;  OUT: /
211
;
1257 hidnplayr 212
;-----------------------------------------------------------------
1159 hidnplayr 213
align 4
214
socket_init:
215
 
1514 hidnplayr 216
	xor	eax, eax
217
	mov	edi, net_sockets
218
	mov	ecx, 4
219
	rep	stosd
1159 hidnplayr 220
 
221
	mov	[last_UDP_port], MIN_EPHEMERAL_PORT
222
	mov	[last_TCP_port], MIN_EPHEMERAL_PORT
223
 
224
	ret
225
 
226
 
1257 hidnplayr 227
;-----------------------------------------------------------------
1159 hidnplayr 228
;
229
; Socket API (function 74)
230
;
1257 hidnplayr 231
;-----------------------------------------------------------------
1159 hidnplayr 232
align 4
233
sys_socket:
1514 hidnplayr 234
	cmp	ebx, 8		; highest possible number
1254 hidnplayr 235
	jg	s_error
236
	lea	ebx, [.table + 4*ebx]
237
	jmp	dword [ebx]
1159 hidnplayr 238
 
1254 hidnplayr 239
.table:
1514 hidnplayr 240
	dd	SOCKET_open	; 0
241
	dd	SOCKET_close	; 1
242
	dd	SOCKET_bind	; 2
243
	dd	SOCKET_listen	; 3
244
	dd	SOCKET_connect	; 4
245
	dd	SOCKET_accept	; 5
246
	dd	SOCKET_send	; 6
247
	dd	SOCKET_receive	; 7
248
	dd	SOCKET_get_opt	; 8
249
;        dd      SOCKET_set_opt  ; 9
1159 hidnplayr 250
 
1254 hidnplayr 251
 
1185 hidnplayr 252
s_error:
1514 hidnplayr 253
	DEBUGF	1,"socket error\n"
254
	mov	dword [esp+32], -1
1159 hidnplayr 255
 
256
	ret
257
 
258
 
1257 hidnplayr 259
;-----------------------------------------------------------------
1159 hidnplayr 260
;
261
; SOCKET_open
262
;
263
;  IN:  domain in ecx
264
;       type in edx
1196 hidnplayr 265
;       protocol in esi
1159 hidnplayr 266
;  OUT: eax is socket num, -1 on error
267
;
1257 hidnplayr 268
;-----------------------------------------------------------------
1206 hidnplayr 269
align 4
1514 hidnplayr 270
SOCKET_open:
1159 hidnplayr 271
 
1514 hidnplayr 272
	DEBUGF	1,"socket_open: domain: %u, type: %u protocol: %x\n", ecx, edx, esi
1159 hidnplayr 273
 
1514 hidnplayr 274
	call	SOCKET_alloc
1185 hidnplayr 275
	jz	s_error
1159 hidnplayr 276
 
1514 hidnplayr 277
	mov	[eax + SOCKET.Domain], ecx
278
	mov	[eax + SOCKET.Type], edx
279
	mov	[eax + SOCKET.Protocol], esi
1159 hidnplayr 280
 
1514 hidnplayr 281
	mov	[esp+32], edi
1318 hidnplayr 282
 
1159 hidnplayr 283
	ret
284
 
285
 
286
 
1257 hidnplayr 287
;-----------------------------------------------------------------
1159 hidnplayr 288
;
289
; SOCKET_bind
290
;
291
;  IN:  socket number in ecx
292
;       pointer to sockaddr struct in edx
293
;       length of that struct in esi
294
;  OUT: 0 on success
295
;
1257 hidnplayr 296
;-----------------------------------------------------------------
1206 hidnplayr 297
align 4
1514 hidnplayr 298
SOCKET_bind:
1159 hidnplayr 299
 
1514 hidnplayr 300
	DEBUGF	1,"socket_bind: socknum: %u sockaddr: %x, length: %u\n", ecx, edx, esi
1159 hidnplayr 301
 
1514 hidnplayr 302
	call	SOCKET_num_to_ptr
1185 hidnplayr 303
	jz	s_error
1159 hidnplayr 304
 
305
	cmp	esi, 2
1185 hidnplayr 306
	jl	s_error
1159 hidnplayr 307
 
308
	cmp	word [edx], AF_INET4
1249 hidnplayr 309
	je	.af_inet4
1159 hidnplayr 310
 
1249 hidnplayr 311
	cmp	word [edx], AF_UNIX
312
	je	.af_unix
313
 
314
	jmp	s_error
315
 
316
  .af_unix:
317
 
318
	; TODO: write code here
319
 
1514 hidnplayr 320
	mov	dword [esp+32], 0
1249 hidnplayr 321
	ret
322
 
1159 hidnplayr 323
  .af_inet4:
324
 
1514 hidnplayr 325
	DEBUGF	1,"af_inet4\n"
326
 
1159 hidnplayr 327
	cmp	esi, 6
1185 hidnplayr 328
	jl	s_error
1159 hidnplayr 329
 
1514 hidnplayr 330
	mov	ecx, [eax + SOCKET.Type]
1249 hidnplayr 331
 
1159 hidnplayr 332
	mov	bx, word [edx + 2]
333
	test	bx, bx
1206 hidnplayr 334
	jz	.find_free
1159 hidnplayr 335
 
1514 hidnplayr 336
	call	SOCKET_check_port
337
;        test    bx, bx
338
	jz	s_error
1206 hidnplayr 339
	jmp	.got_port
1159 hidnplayr 340
 
1249 hidnplayr 341
    .find_free:
1514 hidnplayr 342
	call	SOCKET_find_port
343
;        test    bx, bx
344
	jz	s_error
1159 hidnplayr 345
 
1249 hidnplayr 346
    .got_port:
1519 hidnplayr 347
	DEBUGF	1,"using local port: %u\n", bx
1514 hidnplayr 348
	mov	word [eax + UDP_SOCKET.LocalPort], bx
1159 hidnplayr 349
 
350
	mov	ebx, dword [edx + 4]
1514 hidnplayr 351
	mov	dword [eax + IP_SOCKET.LocalIP], ebx
1159 hidnplayr 352
 
353
	DEBUGF	1,"local ip: %u.%u.%u.%u\n",\
1514 hidnplayr 354
	[eax + IP_SOCKET.LocalIP + 0]:1,[eax + IP_SOCKET.LocalIP + 1]:1,\
355
	[eax + IP_SOCKET.LocalIP + 2]:1,[eax + IP_SOCKET.LocalIP + 3]:1
1159 hidnplayr 356
 
1514 hidnplayr 357
	mov	dword [esp+32], 0
1159 hidnplayr 358
	ret
359
 
360
 
361
 
362
 
1257 hidnplayr 363
;-----------------------------------------------------------------
1159 hidnplayr 364
;
365
; SOCKET_connect
366
;
367
;  IN:  socket number in ecx
368
;       pointer to sockaddr struct in edx
369
;       length of that struct in esi
370
;  OUT: 0 on success
371
;
1257 hidnplayr 372
;-----------------------------------------------------------------
1159 hidnplayr 373
align 4
1514 hidnplayr 374
SOCKET_connect:
1159 hidnplayr 375
 
1514 hidnplayr 376
	DEBUGF	1,"socket_connect: socknum: %u sockaddr: %x, length: %u\n", ecx, edx, esi
1159 hidnplayr 377
 
1514 hidnplayr 378
	call	SOCKET_num_to_ptr
1185 hidnplayr 379
	jz	s_error
1159 hidnplayr 380
 
1254 hidnplayr 381
	cmp	esi, 8
1185 hidnplayr 382
	jl	s_error
1159 hidnplayr 383
 
384
	cmp	word [edx], AF_INET4
385
	je	.af_inet4
386
 
1185 hidnplayr 387
	jmp	s_error
1159 hidnplayr 388
 
389
  .af_inet4:
390
 
1514 hidnplayr 391
	cmp	[eax + SOCKET.Type], IP_PROTO_UDP
1159 hidnplayr 392
	je	.udp
393
 
1514 hidnplayr 394
	cmp	[eax + SOCKET.Type], IP_PROTO_TCP
1206 hidnplayr 395
	je	.tcp
1159 hidnplayr 396
 
1185 hidnplayr 397
	jmp	s_error
1159 hidnplayr 398
 
1254 hidnplayr 399
  .udp:
1159 hidnplayr 400
	mov	bx , word [edx + 2]
1514 hidnplayr 401
	mov	word [eax + UDP_SOCKET.RemotePort], bx
402
	mov	[eax + UDP_SOCKET.firstpacket], 0
1519 hidnplayr 403
	DEBUGF	1,"remote port: %u\n",bx
1159 hidnplayr 404
 
405
	mov	ebx, dword [edx + 4]
1514 hidnplayr 406
	mov	dword [eax + IP_SOCKET.RemoteIP], ebx
1159 hidnplayr 407
	DEBUGF	1,"remote ip: %u.%u.%u.%u\n",[edx+4]:1,[edx+5]:1,[edx+6]:1,[edx+7]:1
408
 
1514 hidnplayr 409
	mov	dword [esp+32], 0
1159 hidnplayr 410
	ret
411
 
412
 
1254 hidnplayr 413
  .tcp:
1514 hidnplayr 414
	; set sequence number
1159 hidnplayr 415
 
1514 hidnplayr 416
	mov	ebx, [TCP_sequence_num]
417
	add	[TCP_sequence_num], 6400
418
	mov	[eax + TCP_SOCKET.ISS], ebx
419
 
1519 hidnplayr 420
	mov	[eax + TCP_SOCKET.timer_keepalive], 120 	; 120*630ms => 75,6 seconds
421
 
1514 hidnplayr 422
	lea	ebx, [eax + SOCKET.lock]
1281 hidnplayr 423
	call	wait_mutex
1159 hidnplayr 424
 
1254 hidnplayr 425
	; fill in remote port and IP
1159 hidnplayr 426
 
1514 hidnplayr 427
;;;;;;        mov     [eax + TCP_SOCKET.wndsizeTimer], 0     ; Reset the window timer.
428
 
1254 hidnplayr 429
	mov	bx , word [edx + 2]
1514 hidnplayr 430
	mov	[eax + TCP_SOCKET.RemotePort], bx
1519 hidnplayr 431
	DEBUGF	1,"remote port: %u\n", bx
1159 hidnplayr 432
 
1254 hidnplayr 433
	mov	ebx, dword [edx + 4]
1514 hidnplayr 434
	mov	[eax + IP_SOCKET.RemoteIP], ebx
1159 hidnplayr 435
 
1254 hidnplayr 436
	; check if local port and IP is ok
1159 hidnplayr 437
 
1514 hidnplayr 438
	cmp	[eax + IP_SOCKET.LocalIP], 0
1254 hidnplayr 439
	jne	@f
1514 hidnplayr 440
	push	[IP_LIST]	    ;;;;; device zero = default
441
	pop	[eax + IP_SOCKET.LocalIP]
1254 hidnplayr 442
       @@:
1159 hidnplayr 443
 
1514 hidnplayr 444
	cmp	[eax + TCP_SOCKET.LocalPort], 0
1254 hidnplayr 445
	jne	@f
1514 hidnplayr 446
	call	SOCKET_find_port
1254 hidnplayr 447
       @@:
1159 hidnplayr 448
 
1519 hidnplayr 449
	DEBUGF	1,"remote port: %u\n", [eax + TCP_SOCKET.LocalPort]:2
450
 
1514 hidnplayr 451
;        mov     [eax + TCP_SOCKET.t_state], TCB_SYN_SENT
452
	call	TCP_output
1159 hidnplayr 453
 
1514 hidnplayr 454
	mov	[eax + SOCKET.lock], 0
1159 hidnplayr 455
 
1514 hidnplayr 456
	mov	dword [esp+32], 0	; success!
1159 hidnplayr 457
	ret
458
 
459
 
1257 hidnplayr 460
;-----------------------------------------------------------------
1159 hidnplayr 461
;
462
; SOCKET_listen
463
;
464
;  IN:  socket number in ecx
465
;       backlog in edx
466
;  OUT: eax is socket num, -1 on error
467
;
1257 hidnplayr 468
;-----------------------------------------------------------------
1206 hidnplayr 469
align 4
1514 hidnplayr 470
SOCKET_listen:
1159 hidnplayr 471
 
1514 hidnplayr 472
	DEBUGF	1,"Socket_listen: socknum: %u backlog: %u\n", ecx, edx
1159 hidnplayr 473
 
1514 hidnplayr 474
	call	SOCKET_num_to_ptr
1185 hidnplayr 475
	jz	s_error
1159 hidnplayr 476
 
1514 hidnplayr 477
	cmp	word [eax + SOCKET.Domain], AF_INET4
1254 hidnplayr 478
	jne	s_error
479
 
1514 hidnplayr 480
	cmp	[eax + SOCKET.Type], IP_PROTO_TCP
1254 hidnplayr 481
	jne	s_error
482
 
1514 hidnplayr 483
	; TODO: check local port number
484
 
1159 hidnplayr 485
	cmp	edx, MAX_backlog
1514 hidnplayr 486
	jle	.ok
487
	mov	edx, MAX_backlog
1159 hidnplayr 488
  .ok:
489
 
1514 hidnplayr 490
	mov	[eax + TCP_SOCKET.backlog], dx
491
	mov	[eax + TCP_SOCKET.t_state], TCB_LISTEN
492
	 or	[eax + SOCKET.options], SO_ACCEPTCON
1159 hidnplayr 493
 
494
	mov	dword [esp+32], 0
1514 hidnplayr 495
 
1159 hidnplayr 496
	ret
497
 
498
 
1257 hidnplayr 499
;-----------------------------------------------------------------
1159 hidnplayr 500
;
501
; SOCKET_accept
502
;
503
;  IN:  socket number in ecx
504
;       addr in edx
505
;       addrlen in esi
506
;  OUT: eax is socket num, -1 on error
507
;
1257 hidnplayr 508
;-----------------------------------------------------------------
1206 hidnplayr 509
align 4
1514 hidnplayr 510
SOCKET_accept:
1159 hidnplayr 511
 
1514 hidnplayr 512
	DEBUGF	1,"Socket_accept: socknum: %u sockaddr: %x, length: %u\n", ecx, edx, esi
1159 hidnplayr 513
 
1514 hidnplayr 514
	call	SOCKET_num_to_ptr
1185 hidnplayr 515
	jz	s_error
1159 hidnplayr 516
 
1514 hidnplayr 517
	cmp	word [eax + SOCKET.Domain], AF_INET4
1249 hidnplayr 518
	je	.af_inet4
519
 
520
	jmp	s_error
521
 
522
  .af_inet4:
523
 
1514 hidnplayr 524
	cmp	[eax + SOCKET.Type], IP_PROTO_TCP
1249 hidnplayr 525
	je	.tcp
526
 
527
	jmp	s_error
528
 
529
  .tcp:
530
 
1514 hidnplayr 531
	lea	ebx, [eax + SOCKET.lock]
1256 clevermous 532
	call	wait_mutex
1514 hidnplayr 533
 
534
	movzx	ebx, [eax + TCP_SOCKET.backlog_cur]
535
	test	ebx, ebx
1256 clevermous 536
	jz	.unlock_err
1514 hidnplayr 537
 
538
	dec	[eax + TCP_SOCKET.backlog_cur]
539
	mov	eax, [eax + TCP_SOCKET.end + (ebx-1)*4]
540
	mov	[eax + SOCKET.lock], 0
541
	mov	dword [esp+32], 0
542
 
543
	call	TCP_output	;;;;;
544
 
1159 hidnplayr 545
	ret
1514 hidnplayr 546
 
1256 clevermous 547
  .unlock_err:
1514 hidnplayr 548
	mov	[eax + SOCKET.lock], 0
1256 clevermous 549
	jmp	s_error
1159 hidnplayr 550
 
551
 
1257 hidnplayr 552
;-----------------------------------------------------------------
1159 hidnplayr 553
;
554
; SOCKET_close
555
;
556
;  IN:  socket number in ecx
557
;  OUT: eax is socket num, -1 on error
558
;
1257 hidnplayr 559
;-----------------------------------------------------------------
1206 hidnplayr 560
align 4
1514 hidnplayr 561
SOCKET_close:
1159 hidnplayr 562
 
1514 hidnplayr 563
	DEBUGF	1,"socket_close: socknum: %u\n", ecx
1159 hidnplayr 564
 
1514 hidnplayr 565
	call	SOCKET_num_to_ptr
1185 hidnplayr 566
	jz	s_error
1159 hidnplayr 567
 
1514 hidnplayr 568
	cmp	[eax + SOCKET.Domain], AF_INET4
1249 hidnplayr 569
	jne	s_error
1159 hidnplayr 570
 
1514 hidnplayr 571
	cmp	[eax + SOCKET.Type], IP_PROTO_UDP
572
	je	.free
1159 hidnplayr 573
 
1514 hidnplayr 574
	cmp	[eax + SOCKET.Type], IP_PROTO_ICMP
575
	je	.free
1159 hidnplayr 576
 
1514 hidnplayr 577
	cmp	[eax + SOCKET.Type], IP_PROTO_TCP
1206 hidnplayr 578
	je	.tcp
1159 hidnplayr 579
 
1185 hidnplayr 580
	jmp	s_error
1159 hidnplayr 581
 
582
  .tcp:
1514 hidnplayr 583
	test	[eax + TCP_SOCKET.t_state], TCB_SYN_RECEIVED  ;;;;;;
584
	jz	.free
1318 hidnplayr 585
 
1514 hidnplayr 586
	call	TCP_output
1159 hidnplayr 587
 
1514 hidnplayr 588
	mov	dword [esp+32], 0
1159 hidnplayr 589
 
1318 hidnplayr 590
	ret
1159 hidnplayr 591
 
1514 hidnplayr 592
;       state must be LISTEN, SYN_SENT, CLOSED or maybe even invalid
593
;       so, we may destroy the socket
594
  .free:
595
	call	SOCKET_free
596
	mov	dword [esp+32], 0
1159 hidnplayr 597
 
598
	ret
599
 
600
 
1257 hidnplayr 601
;-----------------------------------------------------------------
1159 hidnplayr 602
;
603
; SOCKET_receive
604
;
605
;  IN:  socket number in ecx
1249 hidnplayr 606
;       addr to buffer in edx
607
;       length of buffer in esi
1159 hidnplayr 608
;       flags in edi
609
;  OUT: eax is number of bytes copied, -1 on error
610
;
1257 hidnplayr 611
;-----------------------------------------------------------------
1206 hidnplayr 612
align 4
1514 hidnplayr 613
SOCKET_receive:
1159 hidnplayr 614
 
1514 hidnplayr 615
	DEBUGF	1,"socket_receive: socknum: %u bufaddr: %x, buflength: %u, flags: %x\n", ecx, edx, esi, edi
616
 
617
	call	SOCKET_num_to_ptr
1185 hidnplayr 618
	jz	s_error
1159 hidnplayr 619
 
1281 hidnplayr 620
	mov	ebx, esi
1514 hidnplayr 621
	get_from_queue (eax + SOCKET_QUEUE_LOCATION),\
622
		       SOCKET_QUEUE_SIZE,\
623
		       socket_queue_entry.size,\
624
		       s_error
625
		       ; destroys esi and ecx
1281 hidnplayr 626
 
1514 hidnplayr 627
	mov	edi, edx					; addr to buffer
1159 hidnplayr 628
 
1249 hidnplayr 629
	mov	ecx, [esi + socket_queue_entry.data_size]
630
	DEBUGF	1,"Got %u bytes of data\n", ecx
1159 hidnplayr 631
 
1281 hidnplayr 632
	cmp	ecx, ebx
1249 hidnplayr 633
	jle	.large_enough
634
	DEBUGF	1,"Buffer too small...\n"
635
	jmp	s_error
1514 hidnplayr 636
 
1249 hidnplayr 637
  .large_enough:
1514 hidnplayr 638
	push	[esi + socket_queue_entry.buf_ptr]	       ; save the buffer addr so we can clear it later
639
	mov	esi, [esi + socket_queue_entry.data_ptr]
1249 hidnplayr 640
	DEBUGF	1,"Source buffer: %x, real addr: %x\n", [esp], esi
1514 hidnplayr 641
	mov	dword[esp+32+4], ecx				; return number of bytes copied in ebx
1159 hidnplayr 642
 
1514 hidnplayr 643
; copy the data
1249 hidnplayr 644
	shr	ecx, 1
645
	jnc	.nb
646
	movsb
647
.nb:	shr	ecx, 1
648
	jnc	.nw
649
	movsw
1274 hidnplayr 650
.nw:	test	ecx, ecx
651
	jz	.nd
652
	rep	movsd
653
.nd:
1514 hidnplayr 654
; remove the packet     ;;; TODO: only if it is empty!!
1159 hidnplayr 655
 
1514 hidnplayr 656
;;;;        call    TCP_output  ; only if it is tcp
1159 hidnplayr 657
 
1514 hidnplayr 658
	call	kernel_free
659
 
1159 hidnplayr 660
	ret
661
 
662
 
1257 hidnplayr 663
;-----------------------------------------------------------------
1159 hidnplayr 664
;
665
; SOCKET_send
666
;
667
;
668
;  IN:  socket number in ecx
1206 hidnplayr 669
;       pointer to data in edx
670
;       datalength in esi
1159 hidnplayr 671
;       flags in edi
672
;  OUT: -1 on error
673
;
1257 hidnplayr 674
;-----------------------------------------------------------------
1206 hidnplayr 675
align 4
1514 hidnplayr 676
SOCKET_send:
1159 hidnplayr 677
 
1514 hidnplayr 678
	DEBUGF	1,"socket_send: socknum: %u sockaddr: %x, length: %u, flags: %x\n", ecx, edx, esi, edi
1159 hidnplayr 679
 
1514 hidnplayr 680
	call	SOCKET_num_to_ptr
1185 hidnplayr 681
	jz	s_error
1159 hidnplayr 682
 
1514 hidnplayr 683
	cmp	word [eax + SOCKET.Domain], AF_INET4
1206 hidnplayr 684
	je	.af_inet4
685
 
686
	jmp	s_error
687
 
688
  .af_inet4:
1514 hidnplayr 689
	DEBUGF	1,"af_inet4\n"
1206 hidnplayr 690
 
1514 hidnplayr 691
	cmp	[eax + SOCKET.Type], IP_PROTO_TCP
1249 hidnplayr 692
	je	.tcp
1159 hidnplayr 693
 
1514 hidnplayr 694
	cmp	[eax + SOCKET.Type], IP_PROTO_UDP
1159 hidnplayr 695
	je	.udp
696
 
1185 hidnplayr 697
	jmp	s_error
1159 hidnplayr 698
 
699
  .udp:
1514 hidnplayr 700
	DEBUGF	1,"type: UDP\n"
1159 hidnplayr 701
 
1514 hidnplayr 702
; check if local port is valid
703
	cmp	[eax + UDP_SOCKET.LocalPort], 0
1249 hidnplayr 704
	jne	@f
1206 hidnplayr 705
 
1514 hidnplayr 706
	call	SOCKET_find_port
707
	jz	s_error
1206 hidnplayr 708
 
1514 hidnplayr 709
; Now, send the packet
1249 hidnplayr 710
     @@:
1159 hidnplayr 711
	mov	ecx, esi
712
	mov	esi, edx
713
 
1514 hidnplayr 714
	call	UDP_output
1159 hidnplayr 715
 
1514 hidnplayr 716
	mov	dword [esp+32], 0
1159 hidnplayr 717
	ret
718
 
1249 hidnplayr 719
  .tcp:
1514 hidnplayr 720
	DEBUGF	1,"type: TCP\n"
1159 hidnplayr 721
 
1514 hidnplayr 722
; check if local port is valid
723
	cmp	[eax + TCP_SOCKET.LocalPort], 0
1254 hidnplayr 724
	jne	@f
725
 
1514 hidnplayr 726
	call	SOCKET_find_port
727
	jz	s_error
1254 hidnplayr 728
 
729
     @@:
1514 hidnplayr 730
;;;; TODO: queue the data
1254 hidnplayr 731
 
1514 hidnplayr 732
	call	TCP_output
1254 hidnplayr 733
 
1249 hidnplayr 734
	mov	[esp+32], eax
735
	ret
1159 hidnplayr 736
 
1249 hidnplayr 737
 
738
 
739
 
1257 hidnplayr 740
;-----------------------------------------------------------------
1256 clevermous 741
;
1257 hidnplayr 742
; SOCKET_get_options
1256 clevermous 743
;
1514 hidnplayr 744
;  IN:  ecx = socket number
745
;       edx = pointer to the options:
1257 hidnplayr 746
;               dd      level, optname, optval, optlen
1256 clevermous 747
;  OUT: -1 on error
748
;
749
; At moment, uses only pseudo-optname -2 for get last_ack_number for TCP.
750
; TODO: find best way to notify that send()'ed data were acknowledged
1299 clevermous 751
; Also pseudo-optname -3 is valid and returns socket state, one of TCB_*.
1256 clevermous 752
;
1257 hidnplayr 753
;-----------------------------------------------------------------
754
align 4
1514 hidnplayr 755
SOCKET_get_opt:
1257 hidnplayr 756
 
1514 hidnplayr 757
	DEBUGF	1,"socket_get_opt\n"
758
 
759
	call	SOCKET_num_to_ptr
760
	jz	s_error
761
 
1256 clevermous 762
	cmp	dword [edx], IP_PROTO_TCP
1514 hidnplayr 763
	jnz	s_error
1256 clevermous 764
	cmp	dword [edx+4], -2
1299 clevermous 765
	jz	@f
766
	cmp	dword [edx+4], -3
1514 hidnplayr 767
	jnz	s_error
1299 clevermous 768
@@:
1514 hidnplayr 769
;        mov     eax, [edx+12]
770
;        test    eax, eax
771
;        jz      .fail
772
;        cmp     dword [eax], 4
773
;        mov     dword [eax], 4
774
;        jb      .fail
775
;        stdcall net_socket_num_to_addr, ecx
776
;        test    eax, eax
777
;        jz      .fail
778
;        ; todo: check that eax is really TCP socket
779
;        mov     ecx, [eax + TCP_SOCKET.last_ack_number]
780
;        cmp     dword [edx+4], -2
781
;        jz      @f
782
;        mov     ecx, [eax + TCP_SOCKET.state]
1299 clevermous 783
@@:
1256 clevermous 784
	mov	eax, [edx+8]
785
	test	eax, eax
786
	jz	@f
787
	mov	[eax], ecx
788
@@:
1257 hidnplayr 789
	mov	dword [esp+32], 0
1256 clevermous 790
	ret
1159 hidnplayr 791
 
792
 
1257 hidnplayr 793
;-----------------------------------------------------------------
1206 hidnplayr 794
;
1514 hidnplayr 795
; SOCKET_find_port
1206 hidnplayr 796
;
1514 hidnplayr 797
; Fills in the local port number for TCP and UDP sockets
798
; This procedure always works because the number of sockets is
799
; limited to a smaller number then the number of possible ports
1206 hidnplayr 800
;
1514 hidnplayr 801
;  IN:  eax = socket pointer
802
;  OUT: /
1206 hidnplayr 803
;
1257 hidnplayr 804
;-----------------------------------------------------------------
1206 hidnplayr 805
align 4
1514 hidnplayr 806
SOCKET_find_port:
1159 hidnplayr 807
 
1514 hidnplayr 808
	DEBUGF	1,"socket_find_free_port\n"
1159 hidnplayr 809
 
1514 hidnplayr 810
	push	ebx esi ecx
811
 
812
	cmp	[eax + SOCKET.Type], IP_PROTO_UDP
1206 hidnplayr 813
	je	.udp
1159 hidnplayr 814
 
1514 hidnplayr 815
	cmp	[eax + SOCKET.Type], IP_PROTO_TCP
1206 hidnplayr 816
	je	.tcp
1159 hidnplayr 817
 
1514 hidnplayr 818
	jmp	.error
819
 
820
  .done:
821
	mov	[eax + UDP_SOCKET.LocalPort], bx
822
  .error:
823
	pop	ecx esi ebx
824
	ret
825
 
1206 hidnplayr 826
  .udp:
827
	mov	bx, [last_UDP_port]
1514 hidnplayr 828
	call	.findit
829
	mov	[last_UDP_port], bx
830
	jmp	.done
1206 hidnplayr 831
 
832
  .tcp:
833
	mov	bx, [last_TCP_port]
1514 hidnplayr 834
	call	.findit
835
	mov	[last_TCP_port], bx
836
	jmp	.done
1206 hidnplayr 837
 
838
 
1514 hidnplayr 839
  .restart:
840
	mov	bx, MIN_EPHEMERAL_PORT
841
  .findit:
1206 hidnplayr 842
	inc	bx
843
 
844
	cmp	bx, MAX_EPHEMERAL_PORT
1514 hidnplayr 845
	jz	.restart
1206 hidnplayr 846
 
1514 hidnplayr 847
	call	SOCKET_check_port
848
	jz	.findit
1206 hidnplayr 849
 
850
	ret
851
 
1257 hidnplayr 852
 
853
 
854
;-----------------------------------------------------------------
1206 hidnplayr 855
;
1514 hidnplayr 856
; SOCKET_check_port
1206 hidnplayr 857
;
1514 hidnplayr 858
; Checks if a local port number is unused
859
; If the proposed port number is unused, it is filled in in the socket structure
1206 hidnplayr 860
;
1514 hidnplayr 861
;  IN:  eax = socket ptr (to find out if its a TCP/UDP socket)
862
;        bx = proposed socket number
1206 hidnplayr 863
;
1514 hidnplayr 864
;  OUT:  ZF = cleared on error
865
;
1257 hidnplayr 866
;-----------------------------------------------------------------
1206 hidnplayr 867
align 4
1514 hidnplayr 868
SOCKET_check_port:
869
 
870
	DEBUGF	1,"socket_check_port\n"
871
 
872
	mov	ecx, [eax + SOCKET.Type]
1206 hidnplayr 873
	mov	esi, net_sockets
874
 
875
  .next_socket:
1514 hidnplayr 876
	mov	esi, [esi + SOCKET.NextPtr]
1206 hidnplayr 877
	or	esi, esi
878
	jz	.port_ok
879
 
1514 hidnplayr 880
	cmp	[esi + SOCKET.Type], ecx
1206 hidnplayr 881
	jne	.next_socket
882
 
1514 hidnplayr 883
	cmp	[esi + UDP_SOCKET.LocalPort], bx
1206 hidnplayr 884
	jne	.next_socket
885
 
1514 hidnplayr 886
	DEBUGF	1,"local port %u already in use\n", bx
887
	ret
1206 hidnplayr 888
 
889
  .port_ok:
1514 hidnplayr 890
	mov	[eax + UDP_SOCKET.LocalPort], bx
891
	or	bx, bx					; set the zero-flag
892
 
1206 hidnplayr 893
	ret
894
 
895
 
1257 hidnplayr 896
 
897
;-----------------------------------------------------------------
1206 hidnplayr 898
;
1514 hidnplayr 899
; SOCKET_input
1206 hidnplayr 900
;
1249 hidnplayr 901
; Updates a socket with received data
1206 hidnplayr 902
;
1514 hidnplayr 903
; Note: the mutex should already be set !
1206 hidnplayr 904
;
1249 hidnplayr 905
;  IN:  eax = socket ptr
1514 hidnplayr 906
;       ebx = pointer to device struct
907
;       ecx = data size
908
;       esi = ptr to data
909
;       [esp] = ptr to buf
910
;       [esp + 4] = buf size
1249 hidnplayr 911
;
1514 hidnplayr 912
;  OUT: /
1206 hidnplayr 913
;
1257 hidnplayr 914
;-----------------------------------------------------------------
1206 hidnplayr 915
align 4
1514 hidnplayr 916
SOCKET_input:
1206 hidnplayr 917
 
1514 hidnplayr 918
	DEBUGF	1,"socket_input: socket=%x, data=%x size=%u\n", eax, esi, ecx
1206 hidnplayr 919
 
1514 hidnplayr 920
	mov	dword[esp+4], ecx
921
	push	esi
1249 hidnplayr 922
	mov	esi, esp
1514 hidnplayr 923
 
924
	add_to_queue (eax + SOCKET_QUEUE_LOCATION),\
925
		     SOCKET_QUEUE_SIZE,\
926
		     socket_queue_entry.size,\
927
		     SOCKET_input.full
928
 
1249 hidnplayr 929
	DEBUGF	1,"Queued packet successfully\n"
1257 hidnplayr 930
	add	esp, socket_queue_entry.size
1514 hidnplayr 931
	mov	[eax + SOCKET.lock], 0
932
	jmp	SOCKET_notify_owner
1206 hidnplayr 933
 
1514 hidnplayr 934
  .full:
935
	DEBUGF	2,"Socket %x is full!\n", eax
936
	mov	[eax + SOCKET.lock], 0
937
	call	kernel_free
938
	add	esp, 8
1206 hidnplayr 939
 
1514 hidnplayr 940
	ret
941
 
942
;-----------------------------------------------------------------
943
;
944
; SOCKET_notify_owner
945
;
946
; notify's the owner of a socket that something happened
947
;
948
;  IN:  eax = socket ptr
949
;  OUT: /
950
;
951
;-----------------------------------------------------------------
952
align 4
953
SOCKET_notify_owner:
954
 
955
	DEBUGF	1,"socket_notify_owner\n"
956
 
957
	call	SOCKET_check
958
	jz	.error
959
 
960
	push	ecx eax esi
961
 
962
; socket exists, now try to flag an event to the application
963
 
964
	mov	eax, [eax + SOCKET.PID]
1206 hidnplayr 965
	mov	ecx, 1
966
	mov	esi, TASK_DATA + TASKDATA.pid
967
 
968
       .next_pid:
1514 hidnplayr 969
	cmp	[esi], eax
1206 hidnplayr 970
	je	.found_pid
971
	inc	ecx
972
	add	esi, 0x20
973
	cmp	ecx, [TASK_COUNT]
974
	jbe	.next_pid
975
 
1514 hidnplayr 976
; PID not found, TODO: close socket!
977
 
978
	jmp	.error2
979
 
1206 hidnplayr 980
       .found_pid:
981
	shl	ecx, 8
1514 hidnplayr 982
	or	[ecx + SLOT_BASE + APPDATA.event_mask], EVENT_NETWORK
1206 hidnplayr 983
	mov	[check_idle_semaphore], 200
984
 
1514 hidnplayr 985
	DEBUGF	1,"owner notified\n"
986
 
987
  .error2:
988
	pop	esi eax ecx
989
  .error:
990
 
1206 hidnplayr 991
	ret
992
 
993
 
1514 hidnplayr 994
;--------------------------------------------------------------------
995
;
996
; SOCKET_alloc
997
;
1159 hidnplayr 998
; Allocate memory for socket data and put new socket into the list
999
; Newly created socket is initialized with calling PID and number and
1000
; put into beginning of list (which is a fastest way).
1001
;
1514 hidnplayr 1002
; IN:  /
1003
; OUT: eax = 0 on error, socket ptr otherwise
1004
;      edi = socket number
1005
;       ZF = cleared on error
1159 hidnplayr 1006
;
1514 hidnplayr 1007
;--------------------------------------------------------------------
1008
align 4
1009
SOCKET_alloc:
1010
 
1011
	push	ecx ebx
1012
 
1159 hidnplayr 1013
	stdcall kernel_alloc, SOCKETBUFFSIZE
1514 hidnplayr 1014
	DEBUGF	1, "socket_alloc: %x ", eax
1159 hidnplayr 1015
	or	eax, eax
1016
	jz	.exit
1017
 
1514 hidnplayr 1018
; zero-initialize allocated memory
1019
	push	eax edi
1159 hidnplayr 1020
	mov	edi, eax
1021
	mov	ecx, SOCKETBUFFSIZE / 4
1022
	xor	eax, eax
1023
	rep	stosd
1514 hidnplayr 1024
	pop	edi eax
1159 hidnplayr 1025
 
1257 hidnplayr 1026
	init_queue (eax + SOCKET_QUEUE_LOCATION)
1249 hidnplayr 1027
 
1514 hidnplayr 1028
; find first free socket number and use it
1159 hidnplayr 1029
 
1030
	mov	ebx, net_sockets
1031
	xor	ecx, ecx
1032
  .next_socket_number:
1033
	inc	ecx
1034
  .next_socket:
1514 hidnplayr 1035
	mov	ebx, [ebx + SOCKET.NextPtr]
1159 hidnplayr 1036
	or	ebx, ebx
1514 hidnplayr 1037
	jz	.last_socket
1038
	cmp	[ebx + SOCKET.Number], ecx
1159 hidnplayr 1039
	jne	.next_socket
1040
	mov	ebx, net_sockets
1041
	jmp	.next_socket_number
1042
 
1514 hidnplayr 1043
  .last_socket:
1044
	mov	[eax + SOCKET.Number], ecx
1159 hidnplayr 1045
 
1514 hidnplayr 1046
	DEBUGF	1, "(number: %u)\n", ecx
1047
 
1048
; Fill in PID
1049
	mov	ebx, [TASK_BASE]
1050
	mov	ebx, [ebx + TASKDATA.pid]
1051
 
1052
	mov	[eax + SOCKET.PID], ebx
1053
 
1054
; add socket to the list by changing pointers
1055
 
1056
	mov	ebx, [net_sockets + SOCKET.NextPtr]
1057
 
1058
	mov	[eax + SOCKET.PrevPtr], net_sockets
1059
	mov	[eax + SOCKET.NextPtr], ebx
1060
 
1061
	or	ebx, ebx
1062
	jz	@f
1063
	add	ebx, SOCKET.lock	; lock the next socket
1064
	call	wait_mutex
1065
	sub	ebx, SOCKET.lock
1066
	mov	[ebx + SOCKET.PrevPtr], eax
1067
	mov	[ebx + SOCKET.lock], 0
1068
       @@:
1069
 
1070
	mov	[net_sockets + SOCKET.NextPtr], eax
1071
 
1072
	mov	edi, ecx
1073
	or	eax, eax	; used to clear zero flag
1159 hidnplayr 1074
  .exit:
1514 hidnplayr 1075
	pop	ebx ecx
1076
 
1159 hidnplayr 1077
	ret
1078
 
1514 hidnplayr 1079
 
1080
;----------------------------------------------------
1159 hidnplayr 1081
;
1514 hidnplayr 1082
; SOCKET_free
1159 hidnplayr 1083
;
1514 hidnplayr 1084
; Free socket data memory and remove socket from the list
1085
;
1086
; IN:  eax = socket ptr
1087
; OUT: /
1088
;
1089
;----------------------------------------------------
1090
align 4
1091
SOCKET_free:
1159 hidnplayr 1092
 
1514 hidnplayr 1093
	DEBUGF	1, "socket_free: %x\n", eax
1094
 
1095
	call	SOCKET_check
1159 hidnplayr 1096
	jz	.error
1097
 
1514 hidnplayr 1098
	push	ebx
1099
	lea	ebx, [eax + SOCKET.lock]
1100
	call	wait_mutex
1101
 
1102
	DEBUGF	1, "freeing socket..\n"
1103
 
1104
	push	eax				; this will be passed to kernel_free
1105
	mov	ebx, [eax + SOCKET.NextPtr]
1106
	mov	eax, [eax + SOCKET.PrevPtr]
1107
 
1108
	DEBUGF	1, "linking socket %x to socket %x\n", eax, ebx
1109
 
1110
	test	eax, eax
1159 hidnplayr 1111
	jz	@f
1514 hidnplayr 1112
	mov	[eax + SOCKET.NextPtr], ebx
1113
       @@:
1159 hidnplayr 1114
 
1514 hidnplayr 1115
	test	ebx, ebx
1116
	jz	@f
1117
	mov	[ebx + SOCKET.PrevPtr], eax
1118
       @@:
1249 hidnplayr 1119
 
1514 hidnplayr 1120
	call	kernel_free
1121
	pop	ebx
1159 hidnplayr 1122
 
1514 hidnplayr 1123
	DEBUGF	1, "socket is gone!\n"
1124
 
1159 hidnplayr 1125
  .error:
1126
	ret
1127
 
1514 hidnplayr 1128
 
1129
;---------------------------------------------------
1130
;
1131
; SOCKET_num_to_ptr
1132
;
1159 hidnplayr 1133
; Get socket structure address by its number
1134
;
1514 hidnplayr 1135
; IN:  ecx = socket number
1136
; OUT: ecx = 0 on error, socket ptr otherwise
1137
;       ZF = set on error
1159 hidnplayr 1138
;
1514 hidnplayr 1139
;---------------------------------------------------
1140
align 4
1141
SOCKET_num_to_ptr:
1159 hidnplayr 1142
 
1514 hidnplayr 1143
	DEBUGF	1,"socket_num_to_ptr: %u ", ecx
1144
 
1145
	mov	eax, net_sockets
1146
 
1159 hidnplayr 1147
  .next_socket:
1514 hidnplayr 1148
	mov	eax, [eax + SOCKET.NextPtr]
1149
	or	eax, eax
1159 hidnplayr 1150
	jz	.error
1514 hidnplayr 1151
	cmp	[eax + SOCKET.Number], ecx
1159 hidnplayr 1152
	jne	.next_socket
1153
 
1514 hidnplayr 1154
	test	eax, eax
1159 hidnplayr 1155
 
1514 hidnplayr 1156
	DEBUGF	1,"(%x)\n", eax
1159 hidnplayr 1157
  .error:
1158
	ret
1159
 
1514 hidnplayr 1160
 
1161
;---------------------------------------------------
1159 hidnplayr 1162
;
1514 hidnplayr 1163
; SOCKET_ptr_to_num
1159 hidnplayr 1164
;
1514 hidnplayr 1165
; Get socket number by its address
1166
;
1167
; IN:  eax = socket ptr
1168
; OUT: eax = 0 on error, socket num otherwise
1169
;       ZF = set on error
1170
;
1171
;---------------------------------------------------
1172
align 4
1173
SOCKET_ptr_to_num:
1174
 
1175
	DEBUGF	1,"socket_ptr_to_num: %x ", eax
1176
 
1177
	call	SOCKET_check
1159 hidnplayr 1178
	jz	.error
1179
 
1514 hidnplayr 1180
	mov	eax, [eax + SOCKET.Number]
1181
 
1182
	DEBUGF	1,"(%u)\n", eax
1183
 
1184
  .error:
1185
	ret
1186
 
1187
 
1188
;---------------------------------------------------
1189
;
1190
; SOCKET_check
1191
;
1192
; checks if the given value is really a socket ptr
1193
;
1194
; IN:  eax = socket ptr
1195
; OUT: eax = 0 on error, unchanged otherwise
1196
;       ZF = set on error
1197
;
1198
;---------------------------------------------------
1199
align 4
1200
SOCKET_check:
1201
 
1202
	DEBUGF	1,"socket_check\n"
1203
 
1204
	push	ebx
1159 hidnplayr 1205
	mov	ebx, net_sockets
1514 hidnplayr 1206
 
1159 hidnplayr 1207
  .next_socket:
1514 hidnplayr 1208
	mov	ebx, [ebx + SOCKET.NextPtr]
1159 hidnplayr 1209
	or	ebx, ebx
1514 hidnplayr 1210
	jz	.done
1159 hidnplayr 1211
	cmp	ebx, eax
1514 hidnplayr 1212
	jnz	.next_socket
1159 hidnplayr 1213
 
1514 hidnplayr 1214
  .done:
1215
	mov	eax, ebx
1216
	test	eax, eax
1217
	pop	ebx
1218
 
1159 hidnplayr 1219
	ret
1220
 
1514 hidnplayr 1221
 
1222
 
1223
;---------------------------------------------------
1224
;
1225
; SOCKET_check_owner
1226
;
1227
; checks if the caller application owns the socket
1228
;
1229
; IN:  eax = socket ptr
1230
; OUT:  ZF = true/false
1231
;
1232
;---------------------------------------------------
1233
align 4
1234
SOCKET_check_owner:
1235
 
1236
	DEBUGF	1,"socket_check_owner\n"
1237
 
1238
	push	ebx
1239
	mov	ebx, [TASK_BASE]
1240
	mov	ebx, [ecx + TASKDATA.pid]
1241
	cmp	[eax + SOCKET.PID], ebx
1242
	pop	 ebx
1243
 
1159 hidnplayr 1244
	ret
1514 hidnplayr 1245
 
1246
 
1247
 
1248
 
1249
;---------------------------------------------------
1250
;
1251
; SOCKET_process_end
1252
;
1253
; Kernel calls this function when a certain process ends
1254
; This function will check if the process had any open sockets
1255
; And update them accordingly
1256
;
1257
; IN:  eax = pid
1258
; OUT: /
1259
;
1260
;------------------------------------------------------
1261
align 4
1262
SOCKET_process_end:
1263
 
1264
	DEBUGF	1,"socket_process_end: %x\n", eax
1265
 
1266
	push	ebx
1267
	mov	ebx, net_sockets
1268
 
1269
  .next_socket:
1270
 
1271
	mov	ebx, [ebx + SOCKET.NextPtr]
1272
  .test_socket:
1273
	test	ebx, ebx
1274
	jz	.done
1275
 
1276
	cmp	[ebx + SOCKET.PID], eax
1277
	jne	.next_socket
1278
 
1279
	DEBUGF	1,"closing socket %x", eax, ebx
1280
 
1281
	mov	[ebx + SOCKET.PID], 0
1282
 
1283
	cmp	[ebx + SOCKET.Type], IP_PROTO_UDP
1284
	je	.udp
1285
 
1286
	cmp	[ebx + SOCKET.Type], IP_PROTO_TCP
1287
	je	.tcp
1288
 
1289
	jmp	.next_socket	; kill all sockets for given PID
1290
 
1291
  .udp:
1292
	mov	eax, ebx
1293
	mov	ebx, [ebx + SOCKET.NextPtr]
1294
	call	SOCKET_free
1295
	jmp	.test_socket
1296
 
1297
  .tcp:
1298
 
1299
	jmp	.next_socket
1300
 
1301
  .done:
1302
	pop	ebx
1303
 
1304
	ret