Subversion Repositories Kolibri OS

Rev

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

Rev Author Line No. Line
1159 hidnplayr 1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2
;;                                                                 ;;
1763 hidnplayr 3
;; Copyright (C) KolibriOS team 2004-2011. All rights reserved.    ;;
1159 hidnplayr 4
;; Distributed under terms of the GNU General Public License       ;;
5
;;                                                                 ;;
1529 hidnplayr 6
;;    Written by hidnplayr@kolibrios.org,                          ;;
7
;;     and Clevermouse.                                            ;;
1159 hidnplayr 8
;;                                                                 ;;
1529 hidnplayr 9
;;       Based on code by mike.dld                                 ;;
1159 hidnplayr 10
;;                                                                 ;;
1529 hidnplayr 11
;;         GNU GENERAL PUBLIC LICENSE                              ;;
12
;;          Version 2, June 1991                                   ;;
13
;;                                                                 ;;
1159 hidnplayr 14
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
15
 
1206 hidnplayr 16
$Revision: 2305 $
1159 hidnplayr 17
 
1773 hidnplayr 18
 
2305 hidnplayr 19
struct	SOCKET
1249 hidnplayr 20
 
2305 hidnplayr 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
 
2305 hidnplayr 25
	lock			dd ? ; lock mutex
1249 hidnplayr 26
 
2305 hidnplayr 27
	PID			dd ? ; application process id
28
	Domain			dd ? ; INET/UNIX/..
29
	Type			dd ? ; RAW/STREAM/DGRAP
30
	Protocol		dd ? ; ICMP/IPv4/ARP/TCP/UDP
31
	errorcode		dd ?
1249 hidnplayr 32
 
2305 hidnplayr 33
	options 		dd ?
34
	state			dd ?
35
	backlog 		dw ? ; how many incomming connections that can be queued
1249 hidnplayr 36
 
2305 hidnplayr 37
	snd_proc		dd ?
38
	rcv_proc		dd ?
1536 hidnplayr 39
 
2305 hidnplayr 40
ends
1249 hidnplayr 41
 
2305 hidnplayr 42
struct	IP_SOCKET		SOCKET
1254 hidnplayr 43
 
2305 hidnplayr 44
	LocalIP 		rd 4
45
	RemoteIP		rd 4
1318 hidnplayr 46
 
2305 hidnplayr 47
ends
1159 hidnplayr 48
 
2305 hidnplayr 49
struct	TCP_SOCKET		IP_SOCKET
1249 hidnplayr 50
 
2305 hidnplayr 51
	LocalPort		dw ?
52
	RemotePort		dw ?
1514 hidnplayr 53
 
2305 hidnplayr 54
	t_state 		dd ? ; TCB state
55
	t_rxtshift		dd ?
56
	t_rxtcur		dd ?
57
	t_dupacks		dd ?
58
	t_maxseg		dd ?
59
	t_force 		dd ?
60
	t_flags 		dd ?
1514 hidnplayr 61
 
62
;---------------
63
; RFC783 page 21
64
 
65
; send sequence
2305 hidnplayr 66
	SND_UNA 		dd ? ; sequence number of unack'ed sent Packets
67
	SND_NXT 		dd ? ; next send sequence number to use
68
	SND_UP			dd ?
69
	SND_WL1 		dd ? ; window minus one
70
	SND_WL2 		dd ? ;
71
	ISS			dd ? ; initial send sequence number
72
	SND_WND 		dd ? ; send window
1514 hidnplayr 73
 
74
; receive sequence
2305 hidnplayr 75
	RCV_WND 		dw ? ; receive window
76
	RCV_NXT 		dd ? ; next receive sequence number to use
77
	RCV_UP			dd ?
78
	IRS			dd ? ; initial receive sequence number
1514 hidnplayr 79
 
80
;---------------------
81
; Additional variables
82
 
83
; receive variables
2305 hidnplayr 84
	RCV_ADV 		dd ?
1514 hidnplayr 85
 
86
; retransmit variables
2305 hidnplayr 87
	SND_MAX 		dd ?
1514 hidnplayr 88
 
89
; congestion control
2305 hidnplayr 90
	SND_CWND		dd ?
91
	SND_SSTHRESH		dd ?
1514 hidnplayr 92
 
93
;----------------------
94
; Transmit timing stuff
2305 hidnplayr 95
	t_idle			dd ?
96
	t_rtt			dd ?
97
	t_rtseq 		dd ?
98
	t_srtt			dd ?
99
	t_rttvar		dd ?
100
	t_rttmin		dd ?
101
	max_sndwnd		dd ?
1514 hidnplayr 102
 
103
;-----------------
104
; Out-of-band data
2305 hidnplayr 105
	t_oobflags		dd ?
106
	t_iobc			dd ?
107
	t_softerror		dd ?
1514 hidnplayr 108
 
109
 
110
;---------
111
; RFC 1323
2305 hidnplayr 112
	SND_SCALE		db ? ; Scale factor
113
	RCV_SCALE		db ?
114
	request_r_scale 	db ?
115
	requested_s_scale	dd ?
1514 hidnplayr 116
 
2305 hidnplayr 117
	ts_recent		dd ?
118
	ts_recent_age		dd ?
119
	last_ack_sent		dd ?
1514 hidnplayr 120
 
1519 hidnplayr 121
 
122
;-------
123
; Timers
2305 hidnplayr 124
	timer_retransmission	dw ? ; rexmt
125
	timer_persist		dw ?
126
	timer_keepalive 	dw ? ; keepalive/syn timeout
127
	timer_timed_wait	dw ? ; also used as 2msl timer
1519 hidnplayr 128
 
2305 hidnplayr 129
ends
1249 hidnplayr 130
 
2305 hidnplayr 131
struct	UDP_SOCKET		IP_SOCKET
1249 hidnplayr 132
 
2305 hidnplayr 133
	LocalPort		dw ?
134
	RemotePort		dw ?
135
	firstpacket		db ?
1249 hidnplayr 136
 
2305 hidnplayr 137
ends
1249 hidnplayr 138
 
139
 
2305 hidnplayr 140
struct	ICMP_SOCKET
1249 hidnplayr 141
 
2305 hidnplayr 142
	Identifier		dw ?
1514 hidnplayr 143
 
2305 hidnplayr 144
ends
1514 hidnplayr 145
 
146
 
2305 hidnplayr 147
struct	RING_BUFFER
148
	start_ptr		dd ? ; Pointer to start of buffer
149
	end_ptr 		dd ? ; pointer to end of buffer
150
	read_ptr		dd ? ; Read pointer
151
	write_ptr		dd ? ; Write pointer
152
	size			dd ? ; Number of bytes buffered
153
ends
1514 hidnplayr 154
 
2305 hidnplayr 155
struct	STREAM_SOCKET		TCP_SOCKET
1529 hidnplayr 156
 
2305 hidnplayr 157
	rcv			rd sizeof.RING_BUFFER/4
158
	snd			rd sizeof.RING_BUFFER/4
1529 hidnplayr 159
 
2305 hidnplayr 160
ends
1529 hidnplayr 161
 
2305 hidnplayr 162
struct	socket_queue_entry
1529 hidnplayr 163
 
2305 hidnplayr 164
	data_ptr		dd ?
165
	buf_ptr 		dd ?
166
	data_size		dd ?
1529 hidnplayr 167
 
1274 hidnplayr 168
ends
169
 
1514 hidnplayr 170
 
1249 hidnplayr 171
SOCKETBUFFSIZE		equ 4096     ; in bytes
1514 hidnplayr 172
 
1249 hidnplayr 173
SOCKET_QUEUE_SIZE	equ 10	     ; maximum number ofincoming packets queued for 1 socket
1514 hidnplayr 174
; the incoming packet queue for sockets is placed in the socket struct itself, at this location from start
2305 hidnplayr 175
SOCKET_QUEUE_LOCATION	equ (SOCKETBUFFSIZE - SOCKET_QUEUE_SIZE*sizeof.socket_queue_entry - sizeof.queue)
1249 hidnplayr 176
 
1159 hidnplayr 177
uglobal
1514 hidnplayr 178
	net_sockets	rd 4
1543 hidnplayr 179
	last_socket_num dd ?
1159 hidnplayr 180
	last_UDP_port	dw ? ; These values give the number of the last used ephemeral port
181
	last_TCP_port	dw ? ;
182
endg
183
 
184
 
1257 hidnplayr 185
;-----------------------------------------------------------------
1159 hidnplayr 186
;
187
; SOCKET_init
188
;
1257 hidnplayr 189
;-----------------------------------------------------------------
1529 hidnplayr 190
macro	SOCKET_init {
1159 hidnplayr 191
 
1514 hidnplayr 192
	xor	eax, eax
193
	mov	edi, net_sockets
1543 hidnplayr 194
	mov	ecx, 5
1514 hidnplayr 195
	rep	stosd
1159 hidnplayr 196
 
1529 hidnplayr 197
       @@:
198
	pseudo_random eax
199
	cmp	ax, MIN_EPHEMERAL_PORT
2300 hidnplayr 200
	jb	@r
1529 hidnplayr 201
	cmp	ax, MAX_EPHEMERAL_PORT
2300 hidnplayr 202
	ja	@r
1529 hidnplayr 203
	mov	[last_UDP_port], ax
204
 
205
       @@:
206
	pseudo_random eax
207
	cmp	ax, MIN_EPHEMERAL_PORT
2300 hidnplayr 208
	jb	@r
1529 hidnplayr 209
	cmp	ax, MAX_EPHEMERAL_PORT
2300 hidnplayr 210
	ja	@r
1529 hidnplayr 211
	mov	[last_TCP_port], ax
212
 
213
}
214
 
215
 
1257 hidnplayr 216
;-----------------------------------------------------------------
1159 hidnplayr 217
;
218
; Socket API (function 74)
219
;
1257 hidnplayr 220
;-----------------------------------------------------------------
2301 hidnplayr 221
align 16
222
sock_sysfn_table:
223
	dd	SOCKET_open	; 0
224
	dd	SOCKET_close	; 1
225
	dd	SOCKET_bind	; 2
226
	dd	SOCKET_listen	; 3
227
	dd	SOCKET_connect	; 4
228
	dd	SOCKET_accept	; 5
229
	dd	SOCKET_send	; 6
230
	dd	SOCKET_receive	; 7
231
	dd	SOCKET_set_opt	; 8
232
	dd	SOCKET_get_opt	; 9
233
 
234
SOCKET_SYSFUNCS = ($ - sock_sysfn_table)/4
235
 
236
 
1159 hidnplayr 237
align 4
238
sys_socket:
2301 hidnplayr 239
	cmp	ebx, SOCKET_SYSFUNCS-1
2300 hidnplayr 240
	ja	@f
1542 hidnplayr 241
	jmp	dword [sock_sysfn_table + 4*ebx]
1529 hidnplayr 242
       @@:
243
	cmp	ebx, 255
244
	jz	SOCKET_debug
1159 hidnplayr 245
 
1529 hidnplayr 246
s_error:
247
	DEBUGF	1,"socket error\n"
248
	mov	dword [esp+32], -1
249
 
250
	ret
251
 
1159 hidnplayr 252
 
2301 hidnplayr 253
 
1257 hidnplayr 254
;-----------------------------------------------------------------
1159 hidnplayr 255
;
256
; SOCKET_open
257
;
258
;  IN:  domain in ecx
259
;       type in edx
1196 hidnplayr 260
;       protocol in esi
1159 hidnplayr 261
;  OUT: eax is socket num, -1 on error
262
;
1257 hidnplayr 263
;-----------------------------------------------------------------
1206 hidnplayr 264
align 4
1514 hidnplayr 265
SOCKET_open:
1159 hidnplayr 266
 
1536 hidnplayr 267
	DEBUGF	1,"SOCKET_open: domain: %u, type: %u protocol: %x\n", ecx, edx, esi
1159 hidnplayr 268
 
1514 hidnplayr 269
	call	SOCKET_alloc
1185 hidnplayr 270
	jz	s_error
1159 hidnplayr 271
 
1542 hidnplayr 272
	mov	[esp+32], edi			; return socketnumber
273
 
1514 hidnplayr 274
	mov	[eax + SOCKET.Domain], ecx
275
	mov	[eax + SOCKET.Type], edx
276
	mov	[eax + SOCKET.Protocol], esi
1159 hidnplayr 277
 
1529 hidnplayr 278
	cmp	ecx, AF_INET4
1536 hidnplayr 279
	jne	.no_inet4
1529 hidnplayr 280
 
1542 hidnplayr 281
	cmp	edx, SOCK_DGRAM
1536 hidnplayr 282
	je	.udp
283
 
1542 hidnplayr 284
	cmp	edx, SOCK_STREAM
1536 hidnplayr 285
	je	.tcp
1529 hidnplayr 286
 
1541 hidnplayr 287
	cmp	edx, SOCK_RAW
288
	je	.raw
289
 
1536 hidnplayr 290
  .no_inet4:
291
	ret
292
 
1542 hidnplayr 293
align 4
294
  .raw:
1543 hidnplayr 295
	test	esi, esi       ; IP_PROTO_IP
296
	jz	.ip
1529 hidnplayr 297
 
1542 hidnplayr 298
	cmp	esi, IP_PROTO_ICMP
299
	je	.icmp
1529 hidnplayr 300
 
1542 hidnplayr 301
	cmp	esi, IP_PROTO_UDP
302
	je	.udp
1533 hidnplayr 303
 
1542 hidnplayr 304
	cmp	esi, IP_PROTO_TCP
305
	je	.tcp
1536 hidnplayr 306
 
1159 hidnplayr 307
	ret
308
 
1542 hidnplayr 309
align 4
1536 hidnplayr 310
  .udp:
1542 hidnplayr 311
	mov	[eax + SOCKET.Protocol], IP_PROTO_UDP
1536 hidnplayr 312
	mov	[eax + SOCKET.snd_proc], SOCKET_send_udp
1541 hidnplayr 313
	mov	[eax + SOCKET.rcv_proc], SOCKET_receive_dgram
1529 hidnplayr 314
	ret
315
 
1542 hidnplayr 316
align 4
317
  .tcp:
318
	mov	[eax + SOCKET.Protocol], IP_PROTO_TCP
1543 hidnplayr 319
	mov	[eax + SOCKET.snd_proc], SOCKET_send_tcp
320
	mov	[eax + SOCKET.rcv_proc], SOCKET_receive_tcp
1838 hidnplayr 321
 
322
 
323
	mov	[eax + TCP_SOCKET.t_maxseg], 1480	;;;;; FIXME
1543 hidnplayr 324
	ret
1529 hidnplayr 325
 
326
 
1543 hidnplayr 327
align 4
328
  .ip:
329
	mov	[eax + SOCKET.snd_proc], SOCKET_send_ip
330
	mov	[eax + SOCKET.rcv_proc], SOCKET_receive_dgram
1541 hidnplayr 331
	ret
332
 
1542 hidnplayr 333
 
334
align 4
1541 hidnplayr 335
  .icmp:
336
	mov	[eax + SOCKET.snd_proc], SOCKET_send_icmp
337
	mov	[eax + SOCKET.rcv_proc], SOCKET_receive_dgram
338
	ret
339
 
340
 
341
 
1257 hidnplayr 342
;-----------------------------------------------------------------
1159 hidnplayr 343
;
344
; SOCKET_bind
345
;
346
;  IN:  socket number in ecx
347
;       pointer to sockaddr struct in edx
348
;       length of that struct in esi
349
;  OUT: 0 on success
350
;
1257 hidnplayr 351
;-----------------------------------------------------------------
1206 hidnplayr 352
align 4
1514 hidnplayr 353
SOCKET_bind:
1159 hidnplayr 354
 
1514 hidnplayr 355
	DEBUGF	1,"socket_bind: socknum: %u sockaddr: %x, length: %u\n", ecx, edx, esi
1159 hidnplayr 356
 
1514 hidnplayr 357
	call	SOCKET_num_to_ptr
1185 hidnplayr 358
	jz	s_error
1159 hidnplayr 359
 
360
	cmp	esi, 2
2300 hidnplayr 361
	jb	s_error
1159 hidnplayr 362
 
363
	cmp	word [edx], AF_INET4
1249 hidnplayr 364
	je	.af_inet4
1159 hidnplayr 365
 
1249 hidnplayr 366
	cmp	word [edx], AF_UNIX
367
	je	.af_unix
368
 
369
	jmp	s_error
370
 
371
  .af_unix:
372
	; TODO: write code here
373
 
1514 hidnplayr 374
	mov	dword [esp+32], 0
1249 hidnplayr 375
	ret
376
 
1159 hidnplayr 377
  .af_inet4:
378
 
1514 hidnplayr 379
	DEBUGF	1,"af_inet4\n"
380
 
1159 hidnplayr 381
	cmp	esi, 6
2300 hidnplayr 382
	jb	s_error
1159 hidnplayr 383
 
2301 hidnplayr 384
	pushw	[edx + 2]
385
	pop	[eax + UDP_SOCKET.LocalPort]
1159 hidnplayr 386
 
2301 hidnplayr 387
	pushd	[edx + 4]
1543 hidnplayr 388
	pop	[eax + IP_SOCKET.LocalIP]
1159 hidnplayr 389
 
390
	DEBUGF	1,"local ip: %u.%u.%u.%u\n",\
1514 hidnplayr 391
	[eax + IP_SOCKET.LocalIP + 0]:1,[eax + IP_SOCKET.LocalIP + 1]:1,\
392
	[eax + IP_SOCKET.LocalIP + 2]:1,[eax + IP_SOCKET.LocalIP + 3]:1
1159 hidnplayr 393
 
1514 hidnplayr 394
	mov	dword [esp+32], 0
1159 hidnplayr 395
	ret
396
 
397
 
398
 
399
 
1257 hidnplayr 400
;-----------------------------------------------------------------
1159 hidnplayr 401
;
402
; SOCKET_connect
403
;
404
;  IN:  socket number in ecx
405
;       pointer to sockaddr struct in edx
406
;       length of that struct in esi
407
;  OUT: 0 on success
408
;
1257 hidnplayr 409
;-----------------------------------------------------------------
1159 hidnplayr 410
align 4
1514 hidnplayr 411
SOCKET_connect:
1159 hidnplayr 412
 
1541 hidnplayr 413
	DEBUGF	1,"SOCKET_connect: socknum: %u sockaddr: %x, length: %u\n", ecx, edx, esi
1159 hidnplayr 414
 
1514 hidnplayr 415
	call	SOCKET_num_to_ptr
1185 hidnplayr 416
	jz	s_error
1159 hidnplayr 417
 
1254 hidnplayr 418
	cmp	esi, 8
2300 hidnplayr 419
	jb	s_error
1159 hidnplayr 420
 
421
	cmp	word [edx], AF_INET4
422
	je	.af_inet4
423
 
1185 hidnplayr 424
	jmp	s_error
1159 hidnplayr 425
 
426
  .af_inet4:
1543 hidnplayr 427
	cmp	[eax + IP_SOCKET.LocalIP], 0
428
	jne	@f
429
	push	[IP_LIST]
430
	pop	[eax + IP_SOCKET.LocalIP]
431
       @@:
1159 hidnplayr 432
 
1542 hidnplayr 433
	cmp	[eax + SOCKET.Protocol], IP_PROTO_UDP
1159 hidnplayr 434
	je	.udp
435
 
1542 hidnplayr 436
	cmp	[eax + SOCKET.Protocol], IP_PROTO_TCP
1206 hidnplayr 437
	je	.tcp
1159 hidnplayr 438
 
1542 hidnplayr 439
	cmp	[eax + SOCKET.Protocol], IP_PROTO_IP
440
	je	.ip
1541 hidnplayr 441
 
1542 hidnplayr 442
	cmp	[eax + SOCKET.Protocol], IP_PROTO_ICMP
443
	je	.ip
444
 
1185 hidnplayr 445
	jmp	s_error
1159 hidnplayr 446
 
1542 hidnplayr 447
align 4
1254 hidnplayr 448
  .udp:
1543 hidnplayr 449
	lea	ebx, [eax + SOCKET.lock]
450
	call	wait_mutex
451
 
2301 hidnplayr 452
	pushw	[edx + 2]
1543 hidnplayr 453
	pop	[eax + UDP_SOCKET.RemotePort]
454
 
2301 hidnplayr 455
	pushd	[edx + 4]
1543 hidnplayr 456
	pop	[eax + IP_SOCKET.RemoteIP]
457
 
458
	cmp	[eax + UDP_SOCKET.LocalPort], 0
459
	jne	@f
460
	call	SOCKET_find_port
461
       @@:
462
 
1514 hidnplayr 463
	mov	[eax + UDP_SOCKET.firstpacket], 0
1159 hidnplayr 464
 
1543 hidnplayr 465
	push	eax
466
	init_queue (eax + SOCKET_QUEUE_LOCATION)	; Set up data receiving queue
1733 hidnplayr 467
	pop	eax
1159 hidnplayr 468
 
1543 hidnplayr 469
	mov	[eax + SOCKET.lock], 0
1514 hidnplayr 470
	mov	dword [esp+32], 0
1159 hidnplayr 471
	ret
472
 
1542 hidnplayr 473
align 4
1254 hidnplayr 474
  .tcp:
1514 hidnplayr 475
	lea	ebx, [eax + SOCKET.lock]
1281 hidnplayr 476
	call	wait_mutex
1159 hidnplayr 477
 
2301 hidnplayr 478
	pushw	[edx + 2]
1543 hidnplayr 479
	pop	[eax + TCP_SOCKET.RemotePort]
1159 hidnplayr 480
 
2301 hidnplayr 481
	pushd	[edx + 4]
1543 hidnplayr 482
	pop	[eax + IP_SOCKET.RemoteIP]
1159 hidnplayr 483
 
1543 hidnplayr 484
	cmp	[eax + TCP_SOCKET.LocalPort], 0
485
	jne	@f
486
	call	SOCKET_find_port
487
       @@:
1159 hidnplayr 488
 
1529 hidnplayr 489
	mov	[eax + TCP_SOCKET.timer_persist], 0
1831 hidnplayr 490
	mov	[eax + TCP_SOCKET.t_state], TCPS_SYN_SENT
1733 hidnplayr 491
	push	[TCP_sequence_num]
1529 hidnplayr 492
	add	[TCP_sequence_num], 6400
1733 hidnplayr 493
	pop	[eax + TCP_SOCKET.ISS]
1533 hidnplayr 494
	mov	[eax + TCP_SOCKET.timer_keepalive], TCP_time_keep_init
1519 hidnplayr 495
 
1533 hidnplayr 496
	TCP_sendseqinit eax
1529 hidnplayr 497
 
1543 hidnplayr 498
;        mov     [ebx + TCP_SOCKET.timer_retransmission],   ;; todo: create macro to set retransmission timer
1533 hidnplayr 499
 
1543 hidnplayr 500
	mov	ebx, eax
1159 hidnplayr 501
 
1543 hidnplayr 502
	lea	eax, [ebx + STREAM_SOCKET.snd]
503
	call	SOCKET_ring_create
504
 
505
	lea	eax, [ebx + STREAM_SOCKET.rcv]
506
	call	SOCKET_ring_create
507
 
508
	mov	[ebx + SOCKET.lock], 0
1733 hidnplayr 509
 
510
	mov	eax, ebx
511
	call	TCP_output
512
 
1543 hidnplayr 513
	mov	dword [esp+32], 0
1159 hidnplayr 514
	ret
515
 
1542 hidnplayr 516
align 4
517
  .ip:
1543 hidnplayr 518
	lea	ebx, [eax + SOCKET.lock]
519
	call	wait_mutex
520
 
2301 hidnplayr 521
	pushd	[edx + 4]
522
	pop	[eax + IP_SOCKET.RemoteIP]
1159 hidnplayr 523
 
1543 hidnplayr 524
	push	eax
525
	init_queue (eax + SOCKET_QUEUE_LOCATION)	; Set up data receiving queue
526
	pop	eax
527
 
528
	mov	[eax + SOCKET.lock], 0
529
	mov	dword [esp+32], 0
1541 hidnplayr 530
	ret
531
 
532
 
1257 hidnplayr 533
;-----------------------------------------------------------------
1159 hidnplayr 534
;
535
; SOCKET_listen
536
;
537
;  IN:  socket number in ecx
538
;       backlog in edx
539
;  OUT: eax is socket num, -1 on error
540
;
1257 hidnplayr 541
;-----------------------------------------------------------------
1206 hidnplayr 542
align 4
1514 hidnplayr 543
SOCKET_listen:
1159 hidnplayr 544
 
1541 hidnplayr 545
	DEBUGF	1,"SOCKET_listen: socknum: %u backlog: %u\n", ecx, edx
1159 hidnplayr 546
 
1514 hidnplayr 547
	call	SOCKET_num_to_ptr
1185 hidnplayr 548
	jz	s_error
1159 hidnplayr 549
 
2302 hidnplayr 550
	cmp	[eax + SOCKET.Domain], AF_INET4
1254 hidnplayr 551
	jne	s_error
552
 
1542 hidnplayr 553
	cmp	[eax + SOCKET.Protocol], IP_PROTO_TCP
1254 hidnplayr 554
	jne	s_error
555
 
1543 hidnplayr 556
	cmp	[eax + TCP_SOCKET.LocalPort], 0
557
	je	s_error
1514 hidnplayr 558
 
1543 hidnplayr 559
	cmp	[eax + IP_SOCKET.LocalIP], 0
560
	jne	@f
561
	push	[IP_LIST]
562
	pop	[eax + IP_SOCKET.LocalIP]
563
       @@:
564
 
1159 hidnplayr 565
	cmp	edx, MAX_backlog
2300 hidnplayr 566
	jbe	@f
1514 hidnplayr 567
	mov	edx, MAX_backlog
1543 hidnplayr 568
       @@:
1159 hidnplayr 569
 
1543 hidnplayr 570
	mov	[eax + SOCKET.backlog], dx
571
	or	[eax + SOCKET.options], SO_ACCEPTCON
1831 hidnplayr 572
	mov	[eax + TCP_SOCKET.t_state], TCPS_LISTEN
1159 hidnplayr 573
 
1543 hidnplayr 574
	push	eax
575
	init_queue (eax + SOCKET_QUEUE_LOCATION)		; Set up sockets queue
576
	pop	eax
577
 
1159 hidnplayr 578
	mov	dword [esp+32], 0
1514 hidnplayr 579
 
1159 hidnplayr 580
	ret
581
 
582
 
1257 hidnplayr 583
;-----------------------------------------------------------------
1159 hidnplayr 584
;
585
; SOCKET_accept
586
;
587
;  IN:  socket number in ecx
588
;       addr in edx
589
;       addrlen in esi
590
;  OUT: eax is socket num, -1 on error
591
;
1257 hidnplayr 592
;-----------------------------------------------------------------
1206 hidnplayr 593
align 4
1514 hidnplayr 594
SOCKET_accept:
1159 hidnplayr 595
 
1541 hidnplayr 596
	DEBUGF	1,"SOCKET_accept: socknum: %u sockaddr: %x, length: %u\n", ecx, edx, esi
1159 hidnplayr 597
 
1514 hidnplayr 598
	call	SOCKET_num_to_ptr
1185 hidnplayr 599
	jz	s_error
1159 hidnplayr 600
 
1543 hidnplayr 601
	test	[eax + SOCKET.options], SO_ACCEPTCON
602
	jz	s_error
603
 
2302 hidnplayr 604
	cmp	[eax + SOCKET.Domain], AF_INET4
1543 hidnplayr 605
	jne	s_error
1249 hidnplayr 606
 
1542 hidnplayr 607
	cmp	[eax + SOCKET.Protocol], IP_PROTO_TCP
1543 hidnplayr 608
	jne	s_error
1249 hidnplayr 609
 
1543 hidnplayr 610
	get_from_queue (eax + SOCKET_QUEUE_LOCATION), MAX_backlog, 4, s_error
1249 hidnplayr 611
 
1543 hidnplayr 612
	mov	eax, [esi]
613
	call	SOCKET_ptr_to_num
614
	jz	s_error
2303 hidnplayr 615
	mov	[esp+32], eax
1159 hidnplayr 616
	ret
1514 hidnplayr 617
 
1159 hidnplayr 618
 
1257 hidnplayr 619
;-----------------------------------------------------------------
1159 hidnplayr 620
;
621
; SOCKET_close
622
;
623
;  IN:  socket number in ecx
624
;  OUT: eax is socket num, -1 on error
625
;
1257 hidnplayr 626
;-----------------------------------------------------------------
1206 hidnplayr 627
align 4
1514 hidnplayr 628
SOCKET_close:
1159 hidnplayr 629
 
1541 hidnplayr 630
	DEBUGF	1,"SOCKET_close: socknum: %u\n", ecx
1159 hidnplayr 631
 
1514 hidnplayr 632
	call	SOCKET_num_to_ptr
1185 hidnplayr 633
	jz	s_error
1159 hidnplayr 634
 
1514 hidnplayr 635
	cmp	[eax + SOCKET.Domain], AF_INET4
1249 hidnplayr 636
	jne	s_error
1159 hidnplayr 637
 
1542 hidnplayr 638
	cmp	[eax + SOCKET.Protocol], IP_PROTO_UDP
1514 hidnplayr 639
	je	.free
1159 hidnplayr 640
 
1542 hidnplayr 641
	cmp	[eax + SOCKET.Protocol], IP_PROTO_ICMP
1514 hidnplayr 642
	je	.free
1159 hidnplayr 643
 
1542 hidnplayr 644
	cmp	[eax + SOCKET.Protocol], IP_PROTO_IP
645
	je	.free
646
 
647
	cmp	[eax + SOCKET.Protocol], IP_PROTO_TCP
1206 hidnplayr 648
	je	.tcp
1159 hidnplayr 649
 
1185 hidnplayr 650
	jmp	s_error
1159 hidnplayr 651
 
652
  .tcp:
1831 hidnplayr 653
	cmp	[eax + TCP_SOCKET.t_state], TCPS_SYN_RECEIVED	 ; state must be LISTEN, SYN_SENT or CLOSED
2300 hidnplayr 654
	jb	.free
1318 hidnplayr 655
 
1536 hidnplayr 656
	call	TCP_output
657
	mov	dword [esp+32], 0
1159 hidnplayr 658
 
1536 hidnplayr 659
	ret
1159 hidnplayr 660
 
1514 hidnplayr 661
  .free:
662
	call	SOCKET_free
663
	mov	dword [esp+32], 0
1159 hidnplayr 664
 
665
	ret
666
 
667
 
1257 hidnplayr 668
;-----------------------------------------------------------------
1159 hidnplayr 669
;
670
; SOCKET_receive
671
;
672
;  IN:  socket number in ecx
1249 hidnplayr 673
;       addr to buffer in edx
674
;       length of buffer in esi
1159 hidnplayr 675
;       flags in edi
676
;  OUT: eax is number of bytes copied, -1 on error
677
;
1257 hidnplayr 678
;-----------------------------------------------------------------
1206 hidnplayr 679
align 4
1514 hidnplayr 680
SOCKET_receive:
1159 hidnplayr 681
 
1536 hidnplayr 682
	DEBUGF	1,"SOCKET_receive: socknum: %u bufaddr: %x, buflength: %u, flags: %x, ", ecx, edx, esi, edi
1514 hidnplayr 683
 
684
	call	SOCKET_num_to_ptr
1185 hidnplayr 685
	jz	s_error
1159 hidnplayr 686
 
1536 hidnplayr 687
	jmp	[eax + SOCKET.rcv_proc]
1533 hidnplayr 688
 
1536 hidnplayr 689
 
690
align 4
1541 hidnplayr 691
SOCKET_receive_dgram:
1536 hidnplayr 692
 
1541 hidnplayr 693
	DEBUGF	1,"SOCKET_receive: DGRAM\n"
1536 hidnplayr 694
 
1281 hidnplayr 695
	mov	ebx, esi
1514 hidnplayr 696
	mov	edi, edx					; addr to buffer
1159 hidnplayr 697
 
2305 hidnplayr 698
	get_from_queue (eax + SOCKET_QUEUE_LOCATION), SOCKET_QUEUE_SIZE, sizeof.socket_queue_entry, s_error	  ; destroys esi and ecx
1536 hidnplayr 699
 
1249 hidnplayr 700
	mov	ecx, [esi + socket_queue_entry.data_size]
701
	DEBUGF	1,"Got %u bytes of data\n", ecx
1159 hidnplayr 702
 
1281 hidnplayr 703
	cmp	ecx, ebx
2300 hidnplayr 704
	ja	.too_small
1514 hidnplayr 705
 
1536 hidnplayr 706
	push	[esi + socket_queue_entry.buf_ptr]		; save the buffer addr so we can clear it later
1514 hidnplayr 707
	mov	esi, [esi + socket_queue_entry.data_ptr]
1249 hidnplayr 708
	DEBUGF	1,"Source buffer: %x, real addr: %x\n", [esp], esi
2303 hidnplayr 709
	mov	[esp+32+4], ecx 				; return number of bytes copied
1159 hidnplayr 710
 
1514 hidnplayr 711
; copy the data
1249 hidnplayr 712
	shr	ecx, 1
713
	jnc	.nb
714
	movsb
1536 hidnplayr 715
  .nb:
716
	shr	ecx, 1
1249 hidnplayr 717
	jnc	.nw
718
	movsw
1536 hidnplayr 719
  .nw:
720
	test	ecx, ecx
1274 hidnplayr 721
	jz	.nd
722
	rep	movsd
1536 hidnplayr 723
  .nd:
1159 hidnplayr 724
 
1536 hidnplayr 725
	call	kernel_free					; remove the packet
1533 hidnplayr 726
	ret
1514 hidnplayr 727
 
1536 hidnplayr 728
  .too_small:
1533 hidnplayr 729
 
1536 hidnplayr 730
	DEBUGF	1,"Buffer too small...\n"
731
	jmp	s_error
732
 
733
align 4
734
SOCKET_receive_tcp:
735
 
1541 hidnplayr 736
	DEBUGF	1,"SOCKET_receive: TCP\n"
1536 hidnplayr 737
 
1533 hidnplayr 738
	mov	ecx, esi
739
	mov	edi, edx
740
	add	eax, STREAM_SOCKET.rcv
741
	call	SOCKET_ring_read
1534 hidnplayr 742
	call	SOCKET_ring_free
1533 hidnplayr 743
 
2303 hidnplayr 744
	mov	[esp+32], ecx					; return number of bytes copied
1533 hidnplayr 745
 
1159 hidnplayr 746
	ret
747
 
748
 
1257 hidnplayr 749
;-----------------------------------------------------------------
1159 hidnplayr 750
;
751
; SOCKET_send
752
;
753
;
754
;  IN:  socket number in ecx
1206 hidnplayr 755
;       pointer to data in edx
756
;       datalength in esi
1159 hidnplayr 757
;       flags in edi
758
;  OUT: -1 on error
759
;
1257 hidnplayr 760
;-----------------------------------------------------------------
1206 hidnplayr 761
align 4
1514 hidnplayr 762
SOCKET_send:
1159 hidnplayr 763
 
1541 hidnplayr 764
	DEBUGF	1,"SOCKET_send: socknum: %u data ptr: %x, length: %u, flags: %x, ", ecx, edx, esi, edi
1159 hidnplayr 765
 
1514 hidnplayr 766
	call	SOCKET_num_to_ptr
1185 hidnplayr 767
	jz	s_error
1159 hidnplayr 768
 
1763 hidnplayr 769
	mov	ecx, esi
770
	mov	esi, edx
771
 
1536 hidnplayr 772
	jmp	[eax + SOCKET.snd_proc]
1206 hidnplayr 773
 
774
 
1536 hidnplayr 775
align 4
776
SOCKET_send_udp:
1529 hidnplayr 777
 
1541 hidnplayr 778
	DEBUGF	1,"SOCKET_send: UDP\n"
1159 hidnplayr 779
 
1514 hidnplayr 780
	call	UDP_output
1159 hidnplayr 781
 
2303 hidnplayr 782
	mov	[esp+32], eax
1159 hidnplayr 783
	ret
784
 
785
 
1536 hidnplayr 786
align 4
787
SOCKET_send_tcp:
1254 hidnplayr 788
 
1541 hidnplayr 789
	DEBUGF	1,"SOCKET_send: TCP\n"
1254 hidnplayr 790
 
1533 hidnplayr 791
	push	eax
792
	add	eax, STREAM_SOCKET.snd
793
	call	SOCKET_ring_write
794
	pop	eax
1536 hidnplayr 795
 
1514 hidnplayr 796
	call	TCP_output
1254 hidnplayr 797
 
1249 hidnplayr 798
	mov	[esp+32], eax
799
	ret
1159 hidnplayr 800
 
1249 hidnplayr 801
 
1543 hidnplayr 802
align 4
803
SOCKET_send_ip:
1249 hidnplayr 804
 
1543 hidnplayr 805
	DEBUGF	1,"type: IP\n"
806
 
807
	call	IPv4_output_raw
808
 
1763 hidnplayr 809
	mov	[esp+32], eax
1543 hidnplayr 810
	ret
811
 
1541 hidnplayr 812
align 4
813
SOCKET_send_icmp:
1249 hidnplayr 814
 
1541 hidnplayr 815
	DEBUGF	1,"SOCKET_send: ICMP\n"
816
 
817
	call	ICMP_output_raw
818
 
2303 hidnplayr 819
	mov	[esp+32], eax
1541 hidnplayr 820
	ret
821
 
822
 
823
 
824
 
1257 hidnplayr 825
;-----------------------------------------------------------------
1256 clevermous 826
;
1257 hidnplayr 827
; SOCKET_get_options
1256 clevermous 828
;
1514 hidnplayr 829
;  IN:  ecx = socket number
830
;       edx = pointer to the options:
1257 hidnplayr 831
;               dd      level, optname, optval, optlen
1256 clevermous 832
;  OUT: -1 on error
833
;
834
; At moment, uses only pseudo-optname -2 for get last_ack_number for TCP.
835
; TODO: find best way to notify that send()'ed data were acknowledged
1831 hidnplayr 836
; Also pseudo-optname -3 is valid and returns socket state, one of TCPS_*.
1256 clevermous 837
;
1257 hidnplayr 838
;-----------------------------------------------------------------
839
align 4
1514 hidnplayr 840
SOCKET_get_opt:
1257 hidnplayr 841
 
1536 hidnplayr 842
	DEBUGF	1,"SOCKET_get_opt\n"
1514 hidnplayr 843
 
844
	call	SOCKET_num_to_ptr
845
	jz	s_error
846
 
1256 clevermous 847
	cmp	dword [edx], IP_PROTO_TCP
2302 hidnplayr 848
	jne	s_error
1256 clevermous 849
	cmp	dword [edx+4], -2
2302 hidnplayr 850
	je	@f
1299 clevermous 851
	cmp	dword [edx+4], -3
2302 hidnplayr 852
	jne	s_error
1299 clevermous 853
@@:
1514 hidnplayr 854
;        mov     eax, [edx+12]
855
;        test    eax, eax
856
;        jz      .fail
857
;        cmp     dword [eax], 4
858
;        mov     dword [eax], 4
859
;        jb      .fail
860
;        stdcall net_socket_num_to_addr, ecx
861
;        test    eax, eax
862
;        jz      .fail
863
;        ; todo: check that eax is really TCP socket
864
;        mov     ecx, [eax + TCP_SOCKET.last_ack_number]
865
;        cmp     dword [edx+4], -2
866
;        jz      @f
867
;        mov     ecx, [eax + TCP_SOCKET.state]
1299 clevermous 868
@@:
1256 clevermous 869
	mov	eax, [edx+8]
870
	test	eax, eax
871
	jz	@f
872
	mov	[eax], ecx
873
@@:
1257 hidnplayr 874
	mov	dword [esp+32], 0
1256 clevermous 875
	ret
1159 hidnplayr 876
 
877
 
1529 hidnplayr 878
 
1542 hidnplayr 879
 
880
align 4
881
SOCKET_set_opt:
882
 
883
	ret
884
 
885
 
886
 
1257 hidnplayr 887
;-----------------------------------------------------------------
1206 hidnplayr 888
;
1529 hidnplayr 889
; SOCKET_debug
890
;
891
;  Copies socket variables to application buffer
892
;
893
;  IN:  ecx = socket number
894
;       edx = pointer to buffer
895
;
896
;  OUT: -1 on error
897
;-----------------------------------------------------------------
898
align 4
899
SOCKET_debug:
900
 
901
	DEBUGF	1,"socket_debug\n"
902
 
903
	call	SOCKET_num_to_ptr
904
	jz	s_error
905
 
906
	mov	esi, eax
907
	mov	edi, edx
908
	mov	ecx, SOCKETBUFFSIZE/4
909
	rep	movsd
910
 
911
	mov	dword [esp+32], 0
912
	ret
913
 
914
 
915
;-----------------------------------------------------------------
916
;
1514 hidnplayr 917
; SOCKET_find_port
1206 hidnplayr 918
;
1514 hidnplayr 919
; Fills in the local port number for TCP and UDP sockets
920
; This procedure always works because the number of sockets is
921
; limited to a smaller number then the number of possible ports
1206 hidnplayr 922
;
1514 hidnplayr 923
;  IN:  eax = socket pointer
924
;  OUT: /
1206 hidnplayr 925
;
1257 hidnplayr 926
;-----------------------------------------------------------------
1206 hidnplayr 927
align 4
1514 hidnplayr 928
SOCKET_find_port:
1159 hidnplayr 929
 
1536 hidnplayr 930
	DEBUGF	1,"SOCKET_find_port\n"
1159 hidnplayr 931
 
1514 hidnplayr 932
	push	ebx esi ecx
933
 
1542 hidnplayr 934
	cmp	[eax + SOCKET.Protocol], IP_PROTO_UDP
1206 hidnplayr 935
	je	.udp
1159 hidnplayr 936
 
1542 hidnplayr 937
	cmp	[eax + SOCKET.Protocol], IP_PROTO_TCP
1206 hidnplayr 938
	je	.tcp
1159 hidnplayr 939
 
1514 hidnplayr 940
	jmp	.error
941
 
942
  .done:
943
	mov	[eax + UDP_SOCKET.LocalPort], bx
944
  .error:
945
	pop	ecx esi ebx
946
	ret
947
 
1206 hidnplayr 948
  .udp:
949
	mov	bx, [last_UDP_port]
1514 hidnplayr 950
	call	.findit
951
	mov	[last_UDP_port], bx
952
	jmp	.done
1206 hidnplayr 953
 
954
  .tcp:
955
	mov	bx, [last_TCP_port]
1514 hidnplayr 956
	call	.findit
957
	mov	[last_TCP_port], bx
958
	jmp	.done
1206 hidnplayr 959
 
960
 
1514 hidnplayr 961
  .restart:
962
	mov	bx, MIN_EPHEMERAL_PORT
963
  .findit:
1206 hidnplayr 964
	inc	bx
965
 
966
	cmp	bx, MAX_EPHEMERAL_PORT
1514 hidnplayr 967
	jz	.restart
1206 hidnplayr 968
 
1514 hidnplayr 969
	call	SOCKET_check_port
970
	jz	.findit
1206 hidnplayr 971
 
972
	ret
973
 
1257 hidnplayr 974
 
975
 
976
;-----------------------------------------------------------------
1206 hidnplayr 977
;
1542 hidnplayr 978
; SOCKET_check_port (to be used with AF_INET only!)
1206 hidnplayr 979
;
1514 hidnplayr 980
; Checks if a local port number is unused
981
; If the proposed port number is unused, it is filled in in the socket structure
1206 hidnplayr 982
;
1514 hidnplayr 983
;  IN:  eax = socket ptr (to find out if its a TCP/UDP socket)
984
;        bx = proposed socket number
1206 hidnplayr 985
;
1514 hidnplayr 986
;  OUT:  ZF = cleared on error
987
;
1257 hidnplayr 988
;-----------------------------------------------------------------
1206 hidnplayr 989
align 4
1514 hidnplayr 990
SOCKET_check_port:
991
 
1536 hidnplayr 992
	DEBUGF	1,"SOCKET_check_port\n"
1514 hidnplayr 993
 
1542 hidnplayr 994
	mov	ecx, [eax + SOCKET.Protocol]
1206 hidnplayr 995
	mov	esi, net_sockets
996
 
997
  .next_socket:
1514 hidnplayr 998
	mov	esi, [esi + SOCKET.NextPtr]
1206 hidnplayr 999
	or	esi, esi
1000
	jz	.port_ok
1001
 
1542 hidnplayr 1002
	cmp	[esi + SOCKET.Protocol], ecx
1206 hidnplayr 1003
	jne	.next_socket
1004
 
1514 hidnplayr 1005
	cmp	[esi + UDP_SOCKET.LocalPort], bx
1206 hidnplayr 1006
	jne	.next_socket
1007
 
1514 hidnplayr 1008
	DEBUGF	1,"local port %u already in use\n", bx
1009
	ret
1206 hidnplayr 1010
 
1011
  .port_ok:
1514 hidnplayr 1012
	mov	[eax + UDP_SOCKET.LocalPort], bx
1013
	or	bx, bx					; set the zero-flag
1014
 
1206 hidnplayr 1015
	ret
1016
 
1017
 
1257 hidnplayr 1018
 
1019
;-----------------------------------------------------------------
1206 hidnplayr 1020
;
1514 hidnplayr 1021
; SOCKET_input
1206 hidnplayr 1022
;
1536 hidnplayr 1023
; Updates a (stateless) socket with received data
1206 hidnplayr 1024
;
1514 hidnplayr 1025
; Note: the mutex should already be set !
1206 hidnplayr 1026
;
1249 hidnplayr 1027
;  IN:  eax = socket ptr
1514 hidnplayr 1028
;       ebx = pointer to device struct
1029
;       ecx = data size
1030
;       esi = ptr to data
1031
;       [esp] = ptr to buf
1032
;       [esp + 4] = buf size
1249 hidnplayr 1033
;
1514 hidnplayr 1034
;  OUT: /
1206 hidnplayr 1035
;
1257 hidnplayr 1036
;-----------------------------------------------------------------
1206 hidnplayr 1037
align 4
1514 hidnplayr 1038
SOCKET_input:
1206 hidnplayr 1039
 
1536 hidnplayr 1040
	DEBUGF	1,"SOCKET_input: socket=%x, data=%x size=%u\n", eax, esi, ecx
1206 hidnplayr 1041
 
2303 hidnplayr 1042
	mov	[esp+4], ecx
1514 hidnplayr 1043
	push	esi
1249 hidnplayr 1044
	mov	esi, esp
1514 hidnplayr 1045
 
2305 hidnplayr 1046
	add_to_queue (eax + SOCKET_QUEUE_LOCATION), SOCKET_QUEUE_SIZE, sizeof.socket_queue_entry, SOCKET_input.full
1514 hidnplayr 1047
 
1541 hidnplayr 1048
	DEBUGF	1,"SOCKET_input: queued packet successfully\n"
2305 hidnplayr 1049
	add	esp, sizeof.socket_queue_entry
1514 hidnplayr 1050
	mov	[eax + SOCKET.lock], 0
1051
	jmp	SOCKET_notify_owner
1206 hidnplayr 1052
 
1514 hidnplayr 1053
  .full:
1541 hidnplayr 1054
	DEBUGF	2,"SOCKET_input: socket %x is full!\n", eax
1514 hidnplayr 1055
	mov	[eax + SOCKET.lock], 0
1056
	call	kernel_free
1057
	add	esp, 8
1206 hidnplayr 1058
 
1514 hidnplayr 1059
	ret
1060
 
1533 hidnplayr 1061
 
1062
;--------------------------
1063
;
1064
; eax = ptr to ring struct (just a buffer of the right size)
1065
;
1066
align 4
1067
SOCKET_ring_create:
1068
 
1543 hidnplayr 1069
	push	esi
1533 hidnplayr 1070
	mov	esi, eax
1543 hidnplayr 1071
 
1072
	push	edx
1533 hidnplayr 1073
	stdcall create_ring_buffer, SOCKET_MAXDATA, PG_SW
1543 hidnplayr 1074
	pop	edx
1533 hidnplayr 1075
 
1076
	DEBUGF	1,"SOCKET_ring_created: %x\n", eax
1077
	mov	[esi + RING_BUFFER.start_ptr], eax
1078
	mov	[esi + RING_BUFFER.write_ptr], eax
1079
	mov	[esi + RING_BUFFER.read_ptr], eax
1080
	mov	[esi + RING_BUFFER.size], 0
1081
	add	eax,  SOCKET_MAXDATA
1082
	mov	[esi + RING_BUFFER.end_ptr], eax
1543 hidnplayr 1083
	mov	eax, esi
1084
	pop	esi
1533 hidnplayr 1085
 
1086
	ret
1087
 
1514 hidnplayr 1088
;-----------------------------------------------------------------
1089
;
1533 hidnplayr 1090
; SOCKET_ring_write
1529 hidnplayr 1091
;
1533 hidnplayr 1092
; Adds data to a stream socket, and updates write pointer and size
1529 hidnplayr 1093
;
1094
;  IN:  eax = ptr to ring struct
1095
;       ecx = data size
1096
;       esi = ptr to data
1097
;
1533 hidnplayr 1098
;  OUT: ecx = number of bytes stored
1529 hidnplayr 1099
;
1100
;-----------------------------------------------------------------
1101
align 4
1533 hidnplayr 1102
SOCKET_ring_write:
1529 hidnplayr 1103
 
1533 hidnplayr 1104
	DEBUGF	1,"SOCKET_ring_write: ringbuff=%x ptr=%x size=%u\n", eax, esi, ecx
1529 hidnplayr 1105
 
1533 hidnplayr 1106
	add	[eax + RING_BUFFER.size], ecx
1107
	cmp	[eax + RING_BUFFER.size], SOCKET_MAXDATA
2300 hidnplayr 1108
	ja	.too_large
1529 hidnplayr 1109
 
1110
  .copy:
1533 hidnplayr 1111
	mov	edi, [eax + RING_BUFFER.write_ptr]
1541 hidnplayr 1112
	DEBUGF	2,"SOCKET_ring_write: %u bytes from %x to %x\n", ecx, esi, edi
1529 hidnplayr 1113
 
1114
	push	ecx
1533 hidnplayr 1115
	shr	ecx, 1
1116
	jnc	.nb
1117
	movsb
1536 hidnplayr 1118
  .nb:
1533 hidnplayr 1119
	shr	ecx, 1
1120
	jnc	.nw
1121
	movsw
1536 hidnplayr 1122
  .nw:
1533 hidnplayr 1123
	test	ecx, ecx
1124
	jz	.nd
1125
	rep	movsd
1536 hidnplayr 1126
  .nd:
1529 hidnplayr 1127
	pop	ecx
1128
 
1533 hidnplayr 1129
	cmp	edi, [eax + RING_BUFFER.end_ptr]
2300 hidnplayr 1130
	jae	.wrap
1533 hidnplayr 1131
	mov	[eax + RING_BUFFER.write_ptr], edi
1132
 
1529 hidnplayr 1133
	ret
1134
 
1533 hidnplayr 1135
  .wrap:
1136
	sub	edi, SOCKET_MAXDATA
1137
	mov	[eax + RING_BUFFER.write_ptr], edi
1138
 
1139
	ret
1140
 
1529 hidnplayr 1141
  .too_large:
1142
	mov	ecx, SOCKET_MAXDATA				; calculate number of bytes available in buffer
1143
	sub	ecx, [eax + RING_BUFFER.size]
2300 hidnplayr 1144
	jae	.full
1529 hidnplayr 1145
 
1146
	mov	[eax + RING_BUFFER.size], SOCKET_MAXDATA	; update size, we will fill buffer completely
1147
	jmp	.copy
1148
 
1149
  .full:
1541 hidnplayr 1150
	DEBUGF	2,"SOCKET_ring_write: ring buffer is full!\n"
1529 hidnplayr 1151
	xor	ecx, ecx
1152
	ret
1153
 
1154
 
1155
;-----------------------------------------------------------------
1156
;
1157
; SOCKET_ring_read
1158
;
1533 hidnplayr 1159
; reads the data, BUT DOES NOT CLEAR IT FROM MEMORY YET
1529 hidnplayr 1160
;
1161
;  IN:  eax = ptr to ring struct
1162
;       ecx = buffer size
1163
;       edi = ptr to buffer
1164
;
1533 hidnplayr 1165
;  OUT: ecx = number of bytes read
1529 hidnplayr 1166
;
1167
;-----------------------------------------------------------------
1168
align 4
1169
SOCKET_ring_read:
1170
 
1533 hidnplayr 1171
	DEBUGF	1,"SOCKET_ring_read: ringbuff=%x ptr=%x size=%u\n", eax, edi, ecx
1529 hidnplayr 1172
 
1533 hidnplayr 1173
	cmp	ecx, [eax + RING_BUFFER.size]
2300 hidnplayr 1174
	ja	.less_data
1529 hidnplayr 1175
 
1176
  .copy:
1533 hidnplayr 1177
	mov	esi, [eax + RING_BUFFER.read_ptr]
1529 hidnplayr 1178
 
1541 hidnplayr 1179
	DEBUGF	2,"SOCKET_ring_read: %u bytes from %x to %x\n", ecx, esi, edi
1529 hidnplayr 1180
	push	ecx
1533 hidnplayr 1181
	shr	ecx, 1
1182
	jnc	.nb
1183
	movsb
1536 hidnplayr 1184
  .nb:
1533 hidnplayr 1185
	shr	ecx, 1
1186
	jnc	.nw
1187
	movsw
1536 hidnplayr 1188
  .nw:
1533 hidnplayr 1189
	test	ecx, ecx
1190
	jz	.nd
1191
	rep	movsd
1536 hidnplayr 1192
  .nd:
1529 hidnplayr 1193
	pop	ecx
1194
 
1830 hidnplayr 1195
  .no_data_at_all:
1529 hidnplayr 1196
	ret
1197
 
1533 hidnplayr 1198
  .less_data:
1529 hidnplayr 1199
	mov	ecx, [eax + RING_BUFFER.size]
1830 hidnplayr 1200
;        test    ecx, ecx
1533 hidnplayr 1201
;        jz      .no_data_at_all
1529 hidnplayr 1202
	jmp	.copy
1203
 
1204
 
1205
;-----------------------------------------------------------------
1206
;
1207
; SOCKET_ring_free
1208
;
1209
; Free's some bytes from the ringbuffer
1210
;
1211
;  IN:  eax = ptr to ring struct
1212
;       ecx = data size
1213
;
1214
;  OUT: ecx = number of bytes free-ed
1215
;
1216
;-----------------------------------------------------------------
1217
align 4
1218
SOCKET_ring_free:
1219
 
1536 hidnplayr 1220
	DEBUGF	1,"SOCKET_ring_free: %u bytes from ring %x\n", ecx, eax
1529 hidnplayr 1221
 
1222
	sub	[eax + RING_BUFFER.size], ecx
2300 hidnplayr 1223
	jb	.sumthinwong
1529 hidnplayr 1224
	add	[eax + RING_BUFFER.read_ptr], ecx
1225
 
1226
	mov	edx, [eax + RING_BUFFER.end_ptr]
1227
	cmp	[eax + RING_BUFFER.read_ptr], edx
2300 hidnplayr 1228
	jb	@f
1533 hidnplayr 1229
	sub	[eax + RING_BUFFER.read_ptr], SOCKET_MAXDATA
1529 hidnplayr 1230
       @@:
1231
	ret
1232
 
1533 hidnplayr 1233
  .sumthinwong: 	       ; we could free all available bytes, but that would be stupid, i guess..
1234
	add	[eax + RING_BUFFER.size], ecx
1529 hidnplayr 1235
	xor	ecx, ecx
1236
	ret
1237
 
1238
 
1239
;-----------------------------------------------------------------
1240
;
1514 hidnplayr 1241
; SOCKET_notify_owner
1242
;
1243
; notify's the owner of a socket that something happened
1244
;
1245
;  IN:  eax = socket ptr
1246
;  OUT: /
1247
;
1248
;-----------------------------------------------------------------
1249
align 4
1250
SOCKET_notify_owner:
1251
 
1536 hidnplayr 1252
	DEBUGF	1,"SOCKET_notify_owner: %x\n", eax
1514 hidnplayr 1253
 
1254
	call	SOCKET_check
1255
	jz	.error
1256
 
1543 hidnplayr 1257
	push	eax ecx esi
1514 hidnplayr 1258
 
1259
; socket exists, now try to flag an event to the application
1260
 
1261
	mov	eax, [eax + SOCKET.PID]
1206 hidnplayr 1262
	mov	ecx, 1
1263
	mov	esi, TASK_DATA + TASKDATA.pid
1264
 
1265
       .next_pid:
1514 hidnplayr 1266
	cmp	[esi], eax
1206 hidnplayr 1267
	je	.found_pid
1268
	inc	ecx
1269
	add	esi, 0x20
1270
	cmp	ecx, [TASK_COUNT]
1271
	jbe	.next_pid
1272
 
1514 hidnplayr 1273
; PID not found, TODO: close socket!
1274
 
1275
	jmp	.error2
1276
 
1206 hidnplayr 1277
       .found_pid:
1278
	shl	ecx, 8
1514 hidnplayr 1279
	or	[ecx + SLOT_BASE + APPDATA.event_mask], EVENT_NETWORK
1206 hidnplayr 1280
	mov	[check_idle_semaphore], 200
1281
 
1536 hidnplayr 1282
	DEBUGF	1,"SOCKET_notify_owner: succes!\n"
1514 hidnplayr 1283
 
1284
  .error2:
1543 hidnplayr 1285
	pop	esi ecx eax
1536 hidnplayr 1286
 
1514 hidnplayr 1287
  .error:
1288
 
1206 hidnplayr 1289
	ret
1290
 
1291
 
1514 hidnplayr 1292
;--------------------------------------------------------------------
1293
;
1294
; SOCKET_alloc
1295
;
1159 hidnplayr 1296
; Allocate memory for socket data and put new socket into the list
1297
; Newly created socket is initialized with calling PID and number and
1298
; put into beginning of list (which is a fastest way).
1299
;
1514 hidnplayr 1300
; IN:  /
1301
; OUT: eax = 0 on error, socket ptr otherwise
1302
;      edi = socket number
1303
;       ZF = cleared on error
1159 hidnplayr 1304
;
1514 hidnplayr 1305
;--------------------------------------------------------------------
1306
align 4
1307
SOCKET_alloc:
1308
 
1309
	push	ecx ebx
1310
 
1159 hidnplayr 1311
	stdcall kernel_alloc, SOCKETBUFFSIZE
1529 hidnplayr 1312
	DEBUGF	1, "SOCKET_alloc: ptr=%x\n", eax
1159 hidnplayr 1313
	or	eax, eax
1314
	jz	.exit
1315
 
1514 hidnplayr 1316
; zero-initialize allocated memory
1317
	push	eax edi
1159 hidnplayr 1318
	mov	edi, eax
1319
	mov	ecx, SOCKETBUFFSIZE / 4
1320
	xor	eax, eax
1321
	rep	stosd
1514 hidnplayr 1322
	pop	edi eax
1159 hidnplayr 1323
 
1536 hidnplayr 1324
; set send-and receive procedures to return -1
1325
	mov	[eax + SOCKET.snd_proc], s_error
1326
	mov	[eax + SOCKET.rcv_proc], s_error
1327
 
1514 hidnplayr 1328
; find first free socket number and use it
1543 hidnplayr 1329
	mov	ecx, [last_socket_num]
1159 hidnplayr 1330
  .next_socket_number:
1331
	inc	ecx
1543 hidnplayr 1332
	jz	.next_socket_number	; avoid socket nr 0
1333
	cmp	ecx, -1
1334
	je	.next_socket_number	; avoid socket nr -1
1536 hidnplayr 1335
	mov	ebx, net_sockets
1159 hidnplayr 1336
  .next_socket:
1514 hidnplayr 1337
	mov	ebx, [ebx + SOCKET.NextPtr]
1529 hidnplayr 1338
	test	ebx, ebx
1514 hidnplayr 1339
	jz	.last_socket
1536 hidnplayr 1340
 
1514 hidnplayr 1341
	cmp	[ebx + SOCKET.Number], ecx
1159 hidnplayr 1342
	jne	.next_socket
1343
	jmp	.next_socket_number
1344
 
1514 hidnplayr 1345
  .last_socket:
1543 hidnplayr 1346
	mov	[last_socket_num], ecx
1514 hidnplayr 1347
	mov	[eax + SOCKET.Number], ecx
1529 hidnplayr 1348
	DEBUGF	1, "SOCKET_alloc: number=%u\n", ecx
1349
	mov	edi, ecx
1159 hidnplayr 1350
 
1514 hidnplayr 1351
; Fill in PID
1352
	mov	ebx, [TASK_BASE]
1353
	mov	ebx, [ebx + TASKDATA.pid]
1354
	mov	[eax + SOCKET.PID], ebx
1355
 
1529 hidnplayr 1356
; add socket to the list by re-arranging some pointers
1514 hidnplayr 1357
	mov	ebx, [net_sockets + SOCKET.NextPtr]
1358
 
1359
	mov	[eax + SOCKET.PrevPtr], net_sockets
1360
	mov	[eax + SOCKET.NextPtr], ebx
1361
 
1529 hidnplayr 1362
	test	ebx, ebx
1514 hidnplayr 1363
	jz	@f
1364
	add	ebx, SOCKET.lock	; lock the next socket
1365
	call	wait_mutex
1366
	sub	ebx, SOCKET.lock
1367
	mov	[ebx + SOCKET.PrevPtr], eax
1536 hidnplayr 1368
	mov	[ebx + SOCKET.lock], 0	; and unlock it again
1514 hidnplayr 1369
       @@:
1370
 
1371
	mov	[net_sockets + SOCKET.NextPtr], eax
1529 hidnplayr 1372
	or	eax, eax		; used to clear zero flag
1159 hidnplayr 1373
  .exit:
1514 hidnplayr 1374
	pop	ebx ecx
1375
 
1159 hidnplayr 1376
	ret
1377
 
1514 hidnplayr 1378
 
1379
;----------------------------------------------------
1159 hidnplayr 1380
;
1514 hidnplayr 1381
; SOCKET_free
1159 hidnplayr 1382
;
1514 hidnplayr 1383
; Free socket data memory and remove socket from the list
1384
;
1385
; IN:  eax = socket ptr
1386
; OUT: /
1387
;
1388
;----------------------------------------------------
1389
align 4
1390
SOCKET_free:
1159 hidnplayr 1391
 
1536 hidnplayr 1392
	DEBUGF	1, "SOCKET_free: %x\n", eax
1514 hidnplayr 1393
 
1394
	call	SOCKET_check
1159 hidnplayr 1395
	jz	.error
1396
 
1514 hidnplayr 1397
	push	ebx
1398
	lea	ebx, [eax + SOCKET.lock]
1399
	call	wait_mutex
1400
 
1541 hidnplayr 1401
	DEBUGF	1, "SOCKET_free: freeing socket..\n"
1514 hidnplayr 1402
 
1529 hidnplayr 1403
	cmp	[eax + SOCKET.Domain], AF_INET4
1536 hidnplayr 1404
	jnz	.no_tcp
1529 hidnplayr 1405
 
1542 hidnplayr 1406
	cmp	[eax + SOCKET.Protocol], IP_PROTO_TCP
1536 hidnplayr 1407
	jnz	.no_tcp
1529 hidnplayr 1408
 
1536 hidnplayr 1409
	mov	ebx, eax
1410
	stdcall kernel_free, [ebx + STREAM_SOCKET.rcv + RING_BUFFER.start_ptr]
1411
	stdcall kernel_free, [ebx + STREAM_SOCKET.snd + RING_BUFFER.start_ptr]
1412
	mov	eax, ebx
1413
  .no_tcp:
1529 hidnplayr 1414
 
1514 hidnplayr 1415
	push	eax				; this will be passed to kernel_free
1416
	mov	ebx, [eax + SOCKET.NextPtr]
1417
	mov	eax, [eax + SOCKET.PrevPtr]
1418
 
1541 hidnplayr 1419
	DEBUGF	1, "SOCKET_free: linking socket %x to socket %x\n", eax, ebx
1514 hidnplayr 1420
 
1421
	test	eax, eax
1159 hidnplayr 1422
	jz	@f
1514 hidnplayr 1423
	mov	[eax + SOCKET.NextPtr], ebx
1424
       @@:
1159 hidnplayr 1425
 
1514 hidnplayr 1426
	test	ebx, ebx
1427
	jz	@f
1428
	mov	[ebx + SOCKET.PrevPtr], eax
1429
       @@:
1249 hidnplayr 1430
 
1514 hidnplayr 1431
	call	kernel_free
1432
	pop	ebx
1159 hidnplayr 1433
 
1541 hidnplayr 1434
	DEBUGF	1, "SOCKET_free: success!\n"
1514 hidnplayr 1435
 
1159 hidnplayr 1436
  .error:
1437
	ret
1438
 
1543 hidnplayr 1439
;------------------------------------
1440
;
1441
; SOCKET_fork
1442
;
1443
; Create a child socket
1444
;
1533 hidnplayr 1445
; IN:  socket nr in ebx
1543 hidnplayr 1446
; OUT: child socket nr in eax
1447
;
1448
;-----------------------------------
1529 hidnplayr 1449
align 4
1450
SOCKET_fork:
1451
 
1543 hidnplayr 1452
	DEBUGF	1,"SOCKET_fork: %x\n", ebx
1529 hidnplayr 1453
 
1543 hidnplayr 1454
; Exit if backlog queue is full
1455
	mov	eax, [ebx + SOCKET_QUEUE_LOCATION + queue.size]
1456
	cmp	ax, [ebx + SOCKET.backlog]
2300 hidnplayr 1457
	jae	.fail
1543 hidnplayr 1458
 
1529 hidnplayr 1459
; Allocate new socket
1460
	call	SOCKET_alloc
1543 hidnplayr 1461
	jz	.fail
1529 hidnplayr 1462
 
1543 hidnplayr 1463
	push	esi ecx edi
1464
	push	eax
1465
	mov	esi, esp
1466
	add_to_queue (ebx + SOCKET_QUEUE_LOCATION), MAX_backlog, 4, .fail2
1467
	pop	eax
1468
 
1469
; Copy structure from current socket to new
1470
; We start at PID to preserve the socket num, and the 2 pointers at beginning of socket
1471
	lea	esi, [ebx + SOCKET.PID]
1529 hidnplayr 1472
	lea	edi, [eax + SOCKET.PID]
1543 hidnplayr 1473
	mov	ecx, (SOCKET_QUEUE_LOCATION - SOCKET.PID + 3)/4
1529 hidnplayr 1474
	rep	movsd
1475
 
1543 hidnplayr 1476
	and	[eax + SOCKET.options], not SO_ACCEPTCON
1477
	pop	edi ecx esi
1529 hidnplayr 1478
 
1479
	ret
1480
 
1543 hidnplayr 1481
  .fail2:
1482
	add	esp, 4+4+4
1483
  .fail:
1484
	DEBUGF	1,"SOCKET_fork: failed\n"
1485
	xor	eax, eax
1486
	ret
1529 hidnplayr 1487
 
1543 hidnplayr 1488
 
1514 hidnplayr 1489
;---------------------------------------------------
1490
;
1491
; SOCKET_num_to_ptr
1492
;
1159 hidnplayr 1493
; Get socket structure address by its number
1494
;
1514 hidnplayr 1495
; IN:  ecx = socket number
1533 hidnplayr 1496
; OUT: eax = 0 on error, socket ptr otherwise
1514 hidnplayr 1497
;       ZF = set on error
1159 hidnplayr 1498
;
1514 hidnplayr 1499
;---------------------------------------------------
1500
align 4
1501
SOCKET_num_to_ptr:
1159 hidnplayr 1502
 
1536 hidnplayr 1503
	DEBUGF	1,"SOCKET_num_to_ptr: %u ", ecx
1514 hidnplayr 1504
 
1505
	mov	eax, net_sockets
1506
 
1159 hidnplayr 1507
  .next_socket:
1514 hidnplayr 1508
	mov	eax, [eax + SOCKET.NextPtr]
1509
	or	eax, eax
1159 hidnplayr 1510
	jz	.error
1514 hidnplayr 1511
	cmp	[eax + SOCKET.Number], ecx
1159 hidnplayr 1512
	jne	.next_socket
1513
 
1514 hidnplayr 1514
	test	eax, eax
1159 hidnplayr 1515
 
1514 hidnplayr 1516
	DEBUGF	1,"(%x)\n", eax
1159 hidnplayr 1517
  .error:
1518
	ret
1519
 
1514 hidnplayr 1520
 
1521
;---------------------------------------------------
1159 hidnplayr 1522
;
1514 hidnplayr 1523
; SOCKET_ptr_to_num
1159 hidnplayr 1524
;
1514 hidnplayr 1525
; Get socket number by its address
1526
;
1527
; IN:  eax = socket ptr
1528
; OUT: eax = 0 on error, socket num otherwise
1529
;       ZF = set on error
1530
;
1531
;---------------------------------------------------
1532
align 4
1533
SOCKET_ptr_to_num:
1534
 
1536 hidnplayr 1535
	DEBUGF	1,"SOCKET_ptr_to_num: %x ", eax
1514 hidnplayr 1536
 
1537
	call	SOCKET_check
1159 hidnplayr 1538
	jz	.error
1539
 
1514 hidnplayr 1540
	mov	eax, [eax + SOCKET.Number]
1541
 
1542
	DEBUGF	1,"(%u)\n", eax
1543
 
1544
  .error:
1545
	ret
1546
 
1547
 
1548
;---------------------------------------------------
1549
;
1550
; SOCKET_check
1551
;
1552
; checks if the given value is really a socket ptr
1553
;
1554
; IN:  eax = socket ptr
1555
; OUT: eax = 0 on error, unchanged otherwise
1556
;       ZF = set on error
1557
;
1558
;---------------------------------------------------
1559
align 4
1560
SOCKET_check:
1561
 
1536 hidnplayr 1562
	DEBUGF	1,"SOCKET_check: %x\n", eax
1514 hidnplayr 1563
 
1564
	push	ebx
1159 hidnplayr 1565
	mov	ebx, net_sockets
1514 hidnplayr 1566
 
1159 hidnplayr 1567
  .next_socket:
1514 hidnplayr 1568
	mov	ebx, [ebx + SOCKET.NextPtr]
1159 hidnplayr 1569
	or	ebx, ebx
1514 hidnplayr 1570
	jz	.done
1159 hidnplayr 1571
	cmp	ebx, eax
1514 hidnplayr 1572
	jnz	.next_socket
1159 hidnplayr 1573
 
1514 hidnplayr 1574
  .done:
1575
	mov	eax, ebx
1576
	test	eax, eax
1577
	pop	ebx
1578
 
1159 hidnplayr 1579
	ret
1580
 
1514 hidnplayr 1581
 
1582
 
1583
;---------------------------------------------------
1584
;
1585
; SOCKET_check_owner
1586
;
1587
; checks if the caller application owns the socket
1588
;
1589
; IN:  eax = socket ptr
1590
; OUT:  ZF = true/false
1591
;
1592
;---------------------------------------------------
1593
align 4
1594
SOCKET_check_owner:
1595
 
1536 hidnplayr 1596
	DEBUGF	1,"SOCKET_check_owner: %x\n", eax
1514 hidnplayr 1597
 
1598
	push	ebx
1599
	mov	ebx, [TASK_BASE]
1600
	mov	ebx, [ecx + TASKDATA.pid]
1601
	cmp	[eax + SOCKET.PID], ebx
1602
	pop	 ebx
1603
 
1159 hidnplayr 1604
	ret
1514 hidnplayr 1605
 
1606
 
1607
 
1608
 
1885 hidnplayr 1609
;------------------------------------------------------
1514 hidnplayr 1610
;
1611
; SOCKET_process_end
1612
;
1613
; Kernel calls this function when a certain process ends
1614
; This function will check if the process had any open sockets
1615
; And update them accordingly
1616
;
1617
; IN:  eax = pid
1618
; OUT: /
1619
;
1620
;------------------------------------------------------
1621
align 4
1622
SOCKET_process_end:
1623
 
1536 hidnplayr 1624
	DEBUGF	1,"SOCKET_process_end: %x\n", eax
1514 hidnplayr 1625
 
1626
	push	ebx
1627
	mov	ebx, net_sockets
1628
 
1629
  .next_socket:
1630
 
1631
	mov	ebx, [ebx + SOCKET.NextPtr]
1632
  .test_socket:
1633
	test	ebx, ebx
1634
	jz	.done
1635
 
1636
	cmp	[ebx + SOCKET.PID], eax
1637
	jne	.next_socket
1638
 
1639
	DEBUGF	1,"closing socket %x", eax, ebx
1640
 
1641
	mov	[ebx + SOCKET.PID], 0
1642
 
1542 hidnplayr 1643
	cmp	[ebx + SOCKET.Protocol], IP_PROTO_UDP
1514 hidnplayr 1644
	je	.udp
1645
 
1542 hidnplayr 1646
	cmp	[ebx + SOCKET.Protocol], IP_PROTO_TCP
1514 hidnplayr 1647
	je	.tcp
1648
 
1649
	jmp	.next_socket	; kill all sockets for given PID
1650
 
1651
  .udp:
1652
	mov	eax, ebx
1653
	mov	ebx, [ebx + SOCKET.NextPtr]
1654
	call	SOCKET_free
1655
	jmp	.test_socket
1656
 
1657
  .tcp:
1658
 
1885 hidnplayr 1659
	;;; TODO
1660
 
1514 hidnplayr 1661
	jmp	.next_socket
1662
 
1663
  .done:
1664
	pop	ebx
1665
 
1666
	ret
1773 hidnplayr 1667
 
1668
 
1669
 
1670
 
1885 hidnplayr 1671
;-----------------------------------------------------------------
1672
;
1673
; SOCKET_is_connecting
1674
;
1675
;  IN:  eax = socket ptr
1676
;  OUT: /
1677
;
1678
;-----------------------------------------------------------------
1773 hidnplayr 1679
 
1885 hidnplayr 1680
align 4
1681
SOCKET_is_connecting:
1773 hidnplayr 1682
 
1683
 
1885 hidnplayr 1684
	and	[eax + SOCKET.options], not (SS_ISCONNECTED + SS_ISDISCONNECTING + SS_ISCONFIRMING)
1685
	or	[eax + SOCKET.options], SS_ISCONNECTING
1773 hidnplayr 1686
 
1885 hidnplayr 1687
	jmp	SOCKET_notify_owner
1688
 
1689
 
1690
 
1773 hidnplayr 1691
;-----------------------------------------------------------------
1692
;
1885 hidnplayr 1693
; SOCKET_is_connected
1694
;
1695
;  IN:  eax = socket ptr
1696
;  OUT: /
1697
;
1698
;-----------------------------------------------------------------
1699
 
1700
align 4
1701
SOCKET_is_connected:
1702
 
1703
 
1704
	and	[eax + SOCKET.options], not (SS_ISCONNECTING + SS_ISDISCONNECTING + SS_ISCONFIRMING)
1705
	or	[eax + SOCKET.options], SS_ISCONNECTED
1706
 
1707
	jmp	SOCKET_notify_owner
1708
 
1709
 
1710
 
1711
 
1712
;-----------------------------------------------------------------
1713
;
1773 hidnplayr 1714
; SOCKET_is_disconnecting
1715
;
1716
;  IN:  eax = socket ptr
1717
;  OUT: /
1718
;
1719
;-----------------------------------------------------------------
1720
 
1721
align 4
1722
SOCKET_is_disconnecting:
1723
 
1724
	and	[eax + SOCKET.options], not (SS_ISCONNECTING)
1725
	or	[eax + SOCKET.options], SS_ISDISCONNECTING + SS_CANTRCVMORE + SS_CANTSENDMORE
1726
 
1727
	jmp	SOCKET_notify_owner
1728
 
1729
 
1730
 
1731
;-----------------------------------------------------------------
1732
;
1733
; SOCKET_is_disconnected
1734
;
1735
;  IN:  eax = socket ptr
1736
;  OUT: /
1737
;
1738
;-----------------------------------------------------------------
1739
 
1740
align 4
1741
SOCKET_is_disconnected:
1742
 
1743
	and	[eax + SOCKET.options], not (SS_ISCONNECTING + SS_ISCONNECTED + SS_ISDISCONNECTING)
1744
	or	[eax + SOCKET.options], SS_CANTRCVMORE + SS_CANTSENDMORE
1745
 
1746
	jmp	SOCKET_notify_owner
1774 hidnplayr 1747
 
1748
 
1749
;-----------------------------------------------------------------
1750
;
1751
; SOCKET_cant_recv_more
1752
;
1753
;  IN:  eax = socket ptr
1754
;  OUT: /
1755
;
1756
;-----------------------------------------------------------------
1757
 
1758
align 4
1759
SOCKET_cant_recv_more:
1760
 
1885 hidnplayr 1761
	or	[eax + SOCKET.options], SS_CANTRCVMORE
1762
 
1831 hidnplayr 1763
	ret
1764
 
1765
 
1766
 
1767
;-----------------------------------------------------------------
1768
;
1885 hidnplayr 1769
; SOCKET_cant_send_more
1831 hidnplayr 1770
;
1771
;  IN:  eax = socket ptr
1772
;  OUT: /
1773
;
1774
;-----------------------------------------------------------------
1775
 
1776
align 4
1885 hidnplayr 1777
SOCKET_cant_send_more:
1831 hidnplayr 1778
 
1885 hidnplayr 1779
	or	[eax + SOCKET.options], SS_CANTSENDMORE
1831 hidnplayr 1780
 
1885 hidnplayr 1781
	ret