Subversion Repositories Kolibri OS

Rev

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

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