Subversion Repositories Kolibri OS

Rev

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