Subversion Repositories Kolibri OS

Rev

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