Subversion Repositories Kolibri OS

Rev

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

Rev Author Line No. Line
1159 hidnplayr 1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2
;;                                                                 ;;
1196 hidnplayr 3
;; Copyright (C) KolibriOS team 2004-2009. All rights reserved.    ;;
1159 hidnplayr 4
;; Distributed under terms of the GNU General Public License       ;;
5
;;                                                                 ;;
6
;;  SOCKET.INC                                                     ;;
7
;;                                                                 ;;
8
;;                                                                 ;;
9
;;    Written by hidnplayr@kolibrios.org                           ;;
10
;;    based on code by mike.dld                                    ;;
11
;;                                                                 ;;
12
;;          GNU GENERAL PUBLIC LICENSE                             ;;
13
;;             Version 2, June 1991                                ;;
14
;;                                                                 ;;
15
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
16
 
17
$Revision: 1019 $
18
 
19
align 4
20
struct	 SOCKET
21
	 .PrevPtr		dd ? ; pointer to previous socket in list
22
	 .NextPtr		dd ? ; pointer to next socket in list
23
	 .Number		dd ? ; socket number (unique within single process)
24
	 .PID			dd ? ; application process id
25
	 .Domain		dd ? ; INET/UNIX/..
26
	 .Type			dd ? ; RAW/UDP/TCP/...
1196 hidnplayr 27
	 .Protocol		dd ? ; ICMP/IPv4/ARP/
1159 hidnplayr 28
	 .LocalIP		dd ? ; local IP address
29
	 .RemoteIP		dd ? ; remote IP address
30
	 .LocalPort		dw ? ; local port
31
	 .RemotePort		dw ? ; remote port
1196 hidnplayr 32
	 .OrigRemoteIP		dd ? ; original remote IP address (used to reset to LISTEN state)
33
	 .OrigRemotePort	dw ? ; original remote port (used to reset to LISTEN state)
1159 hidnplayr 34
	 .rxDataCount		dd ? ; rx data count
1196 hidnplayr 35
	 .TCBState		dd ? ; TCB state
36
	 .TCBTimer		dd ? ; TCB timer (seconds)
37
	 .ISS			dd ? ; initial send sequence
38
	 .IRS			dd ? ; initial receive sequence
39
	 .SND_UNA		dd ? ; sequence number of unack'ed sent Packets
40
	 .SND_NXT		dd ? ; bext send sequence number to use
41
	 .SND_WND		dd ? ; send window
42
	 .RCV_NXT		dd ? ; next receive sequence number to use
43
	 .RCV_WND		dd ? ; receive window
44
	 .SEG_LEN		dd ? ; segment length
45
	 .SEG_WND		dd ? ; segment window
1159 hidnplayr 46
	 .wndsizeTimer		dd ? ; window size timer
47
	 .lock			dd ? ; lock mutex
48
	 .backlog		dw ? ; Backlog
49
	 .rxData:		     ; receive data buffer here
50
ends
51
 
52
MAX_backlog	equ 20
53
 
54
; socket buffers
55
SOCKETBUFFSIZE		equ 4096  ; state + config + buffer.
56
SOCKETHEADERSIZE	equ SOCKET.rxData ; thus 4096 - SOCKETHEADERSIZE bytes data
57
 
58
uglobal
59
	net_sockets	rd 2
60
	last_UDP_port	dw ? ; These values give the number of the last used ephemeral port
61
	last_TCP_port	dw ? ;
62
endg
63
 
64
 
65
;-----------------------------------------------
66
;
67
; SOCKET_init
68
;
69
;  -
70
;
71
;  IN:  /
72
;  OUT: /
73
;
74
;-----------------------------------------------
75
 
76
align 4
77
socket_init:
78
 
79
	mov	[net_sockets], 0
80
	mov	[net_sockets + 4], 0
81
 
82
	mov	[last_UDP_port], MIN_EPHEMERAL_PORT
83
	mov	[last_TCP_port], MIN_EPHEMERAL_PORT
84
 
85
	ret
86
 
87
 
88
;-----------------------------------------------------------------------------
89
;
90
; Socket API (function 74)
91
;
92
;-----------------------------------------------------------------------------
93
 
94
align 4
95
sys_socket:
96
 
97
	test	bl, bl
98
	jz	socket_open	; 0
99
	dec	bl
100
	jz	socket_close	; 1
101
	dec	bl
102
	jz	socket_bind	; 2
103
	dec	bl
104
	jz	socket_listen	; 3
105
	dec	bl
106
	jz	socket_connect	; 4
107
	dec	bl
108
	jz	socket_accept	; 5
109
	dec	bl
110
	jz	socket_send	; 6
111
	dec	bl
112
	jz	socket_recv	; 7
113
 
1185 hidnplayr 114
s_error:
1159 hidnplayr 115
	mov	dword [esp+32],-1
116
 
117
	ret
118
 
119
 
120
 
121
 
122
;-----------------------------------------------
123
;
124
; SOCKET_open
125
;
126
;
127
;  IN:  domain in ecx
128
;       type in edx
1196 hidnplayr 129
;       protocol in esi
1159 hidnplayr 130
;  OUT: eax is socket num, -1 on error
131
;
132
;-----------------------------------------------
133
socket_open:
134
 
135
	DEBUGF	1,"socket_open: domain: %u, type: %u",ecx, edx
136
 
137
	call	net_socket_alloc
138
	or	eax, eax
1185 hidnplayr 139
	jz	s_error
1159 hidnplayr 140
 
141
	mov	[eax + SOCKET.Domain], ecx
142
	mov	[eax + SOCKET.Type], edx
1196 hidnplayr 143
	mov	[eax + SOCKET.Protocol], esi
1159 hidnplayr 144
 
145
	stdcall net_socket_addr_to_num, eax
146
	DEBUGF	1,", socketnumber: %u\n", eax
147
 
148
	mov	[esp+32], eax
149
 
150
	ret
151
 
152
 
153
 
154
 
155
;-----------------------------------------------
156
;
157
; SOCKET_bind
158
;
159
;  IN:  socket number in ecx
160
;       pointer to sockaddr struct in edx
161
;       length of that struct in esi
162
;  OUT: 0 on success
163
;
164
;-----------------------------------------------
165
 
166
socket_bind:
167
 
168
	DEBUGF	1,"Socket_bind: socknum: %u sockaddr: %x, length: %u, ",ecx,edx,esi
169
 
170
	stdcall net_socket_num_to_addr, ecx
171
	cmp	eax, -1
1185 hidnplayr 172
	jz	s_error
1159 hidnplayr 173
 
174
	cmp	esi, 2
1185 hidnplayr 175
	jl	s_error
1159 hidnplayr 176
 
177
	cmp	word [edx], AF_INET4
178
	je	.af_inet4
179
 
1185 hidnplayr 180
	jmp	s_error
1159 hidnplayr 181
 
182
  .af_inet4:
183
 
184
	cmp	esi, 6
1185 hidnplayr 185
	jl	s_error
1159 hidnplayr 186
 
187
	mov	bx, word [edx + 2]
1196 hidnplayr 188
	rol	bx,8			;;;
1159 hidnplayr 189
	DEBUGF	1,"local port: %u ",bx
190
	test	bx, bx
191
	jnz	.check_only
192
 
193
	mov	bx , [last_UDP_port]
194
 
195
  .find_port_loop:
196
	inc	bx
197
	inc	[last_UDP_port]
198
 
199
  .check_only:
200
	mov	esi, net_sockets
201
 
202
  .next_udp_socket:
203
	mov	esi, [esi + SOCKET.NextPtr]
204
	or	esi, esi
205
	jz	.udp_port_ok
206
 
207
	cmp	[esi + SOCKET.Type], IP_PROTO_UDP
208
	jne	.next_udp_socket
209
 
210
	cmp	[esi + SOCKET.LocalPort], bx
211
	jne	.next_udp_socket
212
 
213
	cmp	word [edx + 2], 0
1185 hidnplayr 214
	jne	s_error
1159 hidnplayr 215
 
216
	cmp	bx, MAX_EPHEMERAL_PORT
217
	jle	.find_port_loop
218
 
219
	mov	[last_UDP_port], MIN_EPHEMERAL_PORT
1185 hidnplayr 220
	jmp	s_error
1159 hidnplayr 221
 
222
  .udp_port_ok:
223
	mov	word [eax + SOCKET.LocalPort], bx
224
 
225
	mov	ebx, dword [edx + 4]
226
	mov	dword [eax + SOCKET.LocalIP], ebx
227
 
228
	DEBUGF	1,"local ip: %u.%u.%u.%u\n",\
229
	[eax + SOCKET.LocalIP]:1,[eax + SOCKET.LocalIP + 1]:1,[eax + SOCKET.LocalIP + 2]:1,[eax + SOCKET.LocalIP + 3]:1
230
 
231
	mov	dword [esp+32],0
232
	ret
233
 
234
 
235
 
236
 
237
;-----------------------------------------------
238
;
239
; SOCKET_connect
240
;
241
;
242
;  IN:  socket number in ecx
243
;       pointer to sockaddr struct in edx
244
;       length of that struct in esi
245
;  OUT: 0 on success
246
;
247
;-----------------------------------------------
248
align 4
249
 
250
socket_connect:
251
 
252
	DEBUGF	1,"Socket_connect: socknum: %u sockaddr: %x, length: %u,",ecx,edx,esi
253
 
254
	stdcall net_socket_num_to_addr, ecx
255
	cmp	eax, -1
1185 hidnplayr 256
	jz	s_error
1159 hidnplayr 257
 
258
	cmp	esi, 2
1185 hidnplayr 259
	jl	s_error
1159 hidnplayr 260
 
261
	cmp	word [edx], AF_INET4
262
	je	.af_inet4
263
 
1185 hidnplayr 264
	jmp	s_error
1159 hidnplayr 265
 
266
  .af_inet4:
267
 
268
	cmp	esi, 8
1185 hidnplayr 269
	jl	s_error
1159 hidnplayr 270
 
271
	cmp	[eax + SOCKET.Type], IP_PROTO_UDP
272
	je	.udp
273
 
274
	cmp	[eax + SOCKET.Type], IP_PROTO_ICMP
275
	je	.icmp
276
 
277
;        cmp     [eax + SOCKET.Type], IP_PROTO_TCP
278
;        je      .tcp
279
 
1185 hidnplayr 280
	jmp	s_error
1159 hidnplayr 281
 
282
  .udp:
283
 
284
	mov	bx , word [edx + 2]
1196 hidnplayr 285
	rol	bx, 8
1159 hidnplayr 286
	mov	word [eax + SOCKET.RemotePort], bx
287
 
288
	DEBUGF	1,"remote port: %u ",bx
289
 
290
	mov	ebx, dword [edx + 4]
291
	mov	dword [eax + SOCKET.RemoteIP], ebx
292
 
293
	DEBUGF	1,"remote ip: %u.%u.%u.%u\n",[edx+4]:1,[edx+5]:1,[edx+6]:1,[edx+7]:1
294
 
295
	mov	dword [esp+32],0
296
	ret
297
 
298
  .icmp:
299
 
300
 
301
	ret
302
 
303
 
304
 
305
  .tcp:
306
 
307
;local sockAddr dd ?
308
 
309
;        cmp     esi, SOCKET_PASSIVE
310
;        jne     .skip_port_check
311
;
312
;        push    ebx
313
;        mov     eax, ebx
314
;        xchg    al, ah
315
;        mov     ebx, net_sockets
316
;
317
;  .next_socket:
318
;        mov     ebx, [ebx + SOCKET.NextPtr]
319
;        or      ebx, ebx
320
;        jz      .last_socket
321
;        cmp     [ebx + SOCKET.TCBState], TCB_LISTEN
322
;        jne     .next_socket
323
;        cmp     [ebx + SOCKET.LocalPort], ax
324
;        jne     .next_socket
325
;
326
;        xchg    al, ah
327
;        DEBUGF  1, "K : error: port %u is listened by 0x%x\n", ax, ebx
328
;        pop     ebx
329
;        jmp     .error
330
;
331
;  .last_socket:
332
;        pop     ebx
333
;
334
;  .skip_port_check:
335
 
336
;        mov     [eax + SOCKET.wndsizeTimer], 0     ; Reset the window timer.
337
;
338
;        xchg    bh, bl
339
;        mov     [eax + SOCKET.LocalPort], bx
340
;        xchg    ch, cl
341
;        mov     [eax + SOCKET.RemotePort], cx
342
;        mov     [eax + SOCKET.OrigRemotePort], cx
343
;        mov     ebx, [IP_LIST]
344
;        mov     [eax + SOCKET.LocalIP], ebx
345
;        mov     [eax + SOCKET.RemoteIP], edx
346
;        mov     [eax + SOCKET.OrigRemoteIP], edx
347
 
348
;        mov     ebx, TCB_LISTEN
349
;        cmp     esi, SOCKET_PASSIVE
350
;        je      @f
351
;        mov     ebx, TCB_SYN_SENT
352
;    @@: mov     [eax + SOCKET.TCBState], ebx            ; Indicate the state of the TCB
353
 
354
;        cmp     ebx, TCB_LISTEN
355
;        je      .exit
356
 
357
	; Now, if we are in active mode, then we have to send a SYN to the specified remote port
358
;        mov     eax, EMPTY_QUEUE
359
;        call    dequeue
360
;        cmp     ax, NO_BUFFER
361
;        je      .exit
362
 
363
;        push    eax
364
 
365
;        mov     bl, TH_SYN
366
;        xor     ecx, ecx
367
;        stdcall build_tcp_Packet, [sockAddr]
368
 
369
;        mov     eax, NET1OUT_QUEUE
370
;        mov     edx, [IP_LIST]
371
;        mov     ecx, [sockAddr]
372
;        cmp     edx, [ecx + SOCKET.RemoteIP]
373
;        jne     .not_local
374
;        mov     eax, IPIN_QUEUE
375
 
376
;  .not_local:
377
	; Send it.
378
;        pop     ebx
379
;        call    queue
380
 
381
  .exit:
382
	xor	eax, eax
383
	ret
384
 
385
 
386
 
387
 
388
;-----------------------------------------------
389
;
390
; SOCKET_listen
391
;
392
;
393
;  IN:  socket number in ecx
394
;       backlog in edx
395
;  OUT: eax is socket num, -1 on error
396
;
397
;-----------------------------------------------
398
 
399
socket_listen:
400
 
401
	DEBUGF	1,"Socket_listen: socknum: %u backlog: %u\n",ecx,edx
402
 
403
	stdcall net_socket_num_to_addr, ecx
404
	cmp	eax, -1
1185 hidnplayr 405
	jz	s_error
1159 hidnplayr 406
 
407
	cmp	edx, MAX_backlog
408
	jl	.ok
409
	mov	dx , 20
410
  .ok:
411
 
412
	mov	[eax + SOCKET.backlog], dx
413
 
414
	; TODO: insert code for active connections like TCP
415
 
416
	mov	dword [esp+32], 0
417
	ret
418
 
419
 
420
 
421
 
422
 
423
 
424
;-----------------------------------------------
425
;
426
; SOCKET_accept
427
;
428
;
429
;  IN:  socket number in ecx
430
;       addr in edx
431
;       addrlen in esi
432
;  OUT: eax is socket num, -1 on error
433
;
434
;-----------------------------------------------
435
 
436
 
437
socket_accept:
438
 
439
	DEBUGF	1,"Socket_accept: socknum: %u sockaddr: %x, length: %u\n",ecx,edx,esi
440
 
441
	stdcall net_socket_num_to_addr, ecx
442
	or	eax, eax
1185 hidnplayr 443
	jz	s_error
1159 hidnplayr 444
	mov	esi, eax
445
 
446
	cmp	[esi + SOCKET.backlog], 0
1185 hidnplayr 447
	jz	s_error
1159 hidnplayr 448
 
449
	call	net_socket_alloc
450
	or	eax, eax
1185 hidnplayr 451
	jz	s_error
1159 hidnplayr 452
	mov	edi, eax
453
 
454
	dec	[esi + SOCKET.backlog]
455
 
456
	mov	ecx, (SOCKET.rxData+3)/4
457
	rep	movsd
458
 
459
	mov	[edi + SOCKET.backlog], 0
460
 
461
	; TODO: fill in structure in ecx
462
 
463
	mov	[esi + SOCKET.RemoteIP], 0
464
	mov	[esi + SOCKET.RemotePort], 0
465
 
466
	stdcall net_socket_addr_to_num, eax
467
	mov	[esp+32], eax
468
 
469
	ret
470
 
471
 
472
 
473
;-----------------------------------------------
474
;
475
; SOCKET_close
476
;
477
;
478
;  IN:  socket number in ecx
479
;  OUT: eax is socket num, -1 on error
480
;
481
;-----------------------------------------------
482
 
483
socket_close:
484
 
485
	DEBUGF	1,"Socket_close: socknum: %u\n",ecx
486
 
487
	stdcall net_socket_num_to_addr, ecx
488
	or	eax, eax
1185 hidnplayr 489
	jz	s_error
1159 hidnplayr 490
 
491
 
492
	cmp	[eax + SOCKET.Type], IP_PROTO_UDP
493
	je	.udp
494
 
495
	cmp	[eax + SOCKET.Type], IP_PROTO_ICMP
496
	je	.icmp
497
 
498
;        cmp     [eax + SOCKET.Type], IP_PROTO_TCP
499
;        je      .tcp
500
 
1185 hidnplayr 501
	jmp	s_error
1159 hidnplayr 502
 
503
  .udp:
504
 
505
	lea	ebx, [eax + SOCKET.lock]
506
	call	wait_mutex
507
	; TODO: mark the socket for deletion, using the mutex
508
 
509
	stdcall net_socket_free, eax
510
 
511
	mov	dword [esp+32],0
512
	ret
513
 
514
 
515
  .icmp:
516
 
517
 
518
 
519
	ret
520
 
521
  .tcp:
522
 
523
if 1 = 0
524
;local sockAddr dd ?
525
 
526
;        DEBUGF  1, "K : socket_close_tcp (0x%x)\n", ebx
527
	; first, remove any resend entries
528
	pusha
529
 
530
	mov	esi, resendQ
531
	mov	ecx, 0
532
 
533
  .next_resendq:
534
	cmp	ecx, NUMRESENDENTRIES
535
	je	.last_resendq	    ; None left
536
	cmp	[esi + 4], ebx
537
	je	@f		    ; found one
538
	inc	ecx
539
	add	esi, 8
540
	jmp	.next_resendq
541
 
542
    @@: mov	dword[esi + 4], 0
543
	inc	ecx
544
	add	esi, 8
545
	jmp	.next_resendq
546
 
547
  .last_resendq:
548
	popa
549
 
550
	mov	ebx, eax
551
;        mov     [sockAddr], eax
552
 
553
	cmp	[eax + SOCKET.TCBState], TCB_LISTEN
554
	je	.destroy_tcb
555
	cmp	[eax + SOCKET.TCBState], TCB_SYN_SENT
556
	je	.destroy_tcb
557
 
558
; Now construct the response, and queue for sending by IP
559
	mov	eax, EMPTY_QUEUE
560
	call	dequeue
561
	cmp	ax, NO_BUFFER
562
	je	.error
563
 
564
	push	eax
565
 
566
	mov	bl, TH_FIN
567
	xor	ecx, ecx
568
	xor	esi, esi
569
	stdcall build_tcp_Packet, [sockAddr]
570
 
571
	mov	 ebx, [sockAddr]
572
	; increament SND.NXT in socket
573
	lea	esi, [ebx + SOCKET.SND_NXT]
574
	call	inc_inet_esi
575
 
576
	; Get the socket state
577
	mov	eax, [ebx + SOCKET.TCBState]
578
	cmp	eax, TCB_SYN_RECEIVED
579
	je	.fin_wait_1
580
	cmp	eax, TCB_ESTABLISHED
581
	je	.fin_wait_1
582
 
583
	; assume CLOSE WAIT
584
	; Send a fin, then enter last-ack state
585
	mov	[ebx + SOCKET.TCBState], TCB_LAST_ACK
586
	jmp	.send
587
 
588
  .fin_wait_1:
589
	; Send a fin, then enter finwait2 state
590
	mov	[ebx + SOCKET.TCBState], TCB_FIN_WAIT_1
591
 
592
  .send:
593
	mov	eax, NET1OUT_QUEUE
594
	mov	edx, [IP_LIST]
595
;        mov     ecx, [sockAddr]
596
	cmp	edx, [ecx + SOCKET.RemoteIP]
597
	jne	.not_local
598
	mov	eax, IPIN_QUEUE
599
 
600
  .not_local:
601
	; Send it.
602
	pop	ebx
603
	call	queue
604
	jmp	.exit
605
 
606
 
607
  .destroy_tcb:
608
 
609
	stdcall net_socket_free, eax
610
 
611
end if
612
 
613
  .exit:
614
	mov	dword [esp+32],0
615
	ret
616
 
617
 
618
 
619
 
620
;-----------------------------------------------
621
;
622
; SOCKET_receive
623
;
624
;
625
;  IN:  socket number in ecx
626
;       addr in edx
627
;       addrlen in esi
628
;       flags in edi
629
;  OUT: eax is number of bytes copied, -1 on error
630
;
631
;-----------------------------------------------
632
 
633
socket_recv:
634
 
635
	DEBUGF	1,"Socket_receive: socknum: %u sockaddr: %x, length: %u, flags: %x\n",ecx,edx,esi,edi
636
 
637
	stdcall net_socket_num_to_addr, ecx		   ; get real socket address
638
	or	eax, eax
1185 hidnplayr 639
	jz	s_error
1159 hidnplayr 640
 
641
	DEBUGF 1,"real socket address:%x\n", eax
642
 
643
	mov	dword[esp+32], -1
644
 
645
	mov	edi, edx
646
 
647
	lea	ebx, [eax + SOCKET.lock]
648
	call	wait_mutex
649
 
650
	mov	ecx, [eax + SOCKET.rxDataCount] 	   ; get count of bytes
651
	DEBUGF 1,"bytes in socket:%u\n", ecx
652
	test	ecx, ecx				   ; if count of bytes is zero..
653
	jz	.exit					   ; exit function (eax will be zero)
654
 
655
	cmp	ecx, esi				   ; if buffer size is larger then the bytes of data, copy all data
656
	jle	.copy_all_bytes
657
 
658
	sub	ecx, esi				   ; store new count (data bytes in buffer - bytes we're about to copy)
659
	mov	[eax + SOCKET.rxDataCount], ecx 	   ;
660
	push	ecx
661
	mov	edx, esi
662
 
663
	call	.start_copy				   ; copy to the application
664
 
665
	mov	dword[esp+32], edx
666
 
667
	lea	edi, [eax + SOCKET.rxData]		   ; Now shift the remaining bytes to start of buffer
668
	lea	esi, [edi + edx]
669
	mov	ecx, [esp]
670
	shr	ecx, 2					   ; divide eax by 4
671
	rep	movsd					   ; copy all full dwords
672
	pop	ecx
673
	and	ecx, 3
674
	rep	movsb					   ; copy remaining bytes
675
 
676
  .exit:
677
	mov	[eax + SOCKET.lock], 0
678
	ret
679
 
680
  .copy_all_bytes:
681
	mov	dword[esp+32], ecx
682
	mov	[eax + SOCKET.rxDataCount], 0		  ; store new count (zero)
683
	push	dword .exit				   ; this code results in same as commented out code
684
 
685
  .start_copy:
686
	DEBUGF	1,"copying %u bytes\n",ecx
687
 
688
	lea	esi, [eax + SOCKET.rxData]
689
	push	ecx
690
	shr	ecx, 2					   ; divide eax by 4
691
	rep	movsd
692
	pop	ecx
693
	and	ecx, 3
694
	rep	movsb					   ; copy the rest bytes
695
 
696
	ret						   ; exit, or go back to shift remaining bytes if any
697
 
698
 
699
 
700
;-----------------------------------------------
701
;
702
; SOCKET_send
703
;
704
;
705
;  IN:  socket number in ecx
706
;       addr in edx
707
;       addrlen in esi
708
;       flags in edi
709
;  OUT: -1 on error
710
;
711
;-----------------------------------------------
712
 
713
socket_send:
714
 
715
	DEBUGF	1,"Socket_send: socknum: %u sockaddr: %x, length: %u, flags: %x, ",ecx,edx,esi,edi
716
 
717
	stdcall net_socket_num_to_addr, ecx		   ; get real socket address
718
	or	eax, eax
1185 hidnplayr 719
	jz	s_error
1159 hidnplayr 720
 
721
	DEBUGF	1,"Socket type:%u\n", [eax + SOCKET.Type]:4
722
 
723
	cmp	[eax + SOCKET.Type], IP_PROTO_UDP
724
	je	.udp
725
 
726
	cmp	[eax + SOCKET.Type], IP_PROTO_ICMP
727
	je	.icmp
728
 
729
;        cmp     [eax + SOCKET.Type], IP_PROTO_TCP
730
;        je      .tcp
731
 
1185 hidnplayr 732
	jmp	s_error
1159 hidnplayr 733
 
734
  .udp:
735
 
736
	DEBUGF	1,"type: UDP\n"
737
 
738
	mov	ecx, esi
739
	mov	esi, edx
740
	mov	edx, dword [eax + SOCKET.LocalPort] ; load local port and remote port at once
741
	DEBUGF	1,"local port: %u, remote port:%u\n",[eax + SOCKET.LocalPort]:2, [eax + SOCKET.RemotePort]:2
1196 hidnplayr 742
	bswap	edx	 ;;;
743
	rol	edx, 16  ;;;
1159 hidnplayr 744
	mov	ebx, [eax + SOCKET.LocalIP]
745
	mov	eax, [eax + SOCKET.RemoteIP]
746
 
1196 hidnplayr 747
	call	UDP_create_packet
1159 hidnplayr 748
 
749
	mov	[esp+32], eax
750
	ret
751
 
752
  .icmp:
753
	; note: for ICMP sockets the SOCKET.LocalPort is used as the 'Identifier' value for ICMP packets
754
	; the application must add the header to the data, the kernel will fill in 'identifier' and 'checksum'
755
 
756
	sub	ecx, ICMP_Packet.Data
757
	mov	esi, edx
758
	push	ax
759
	call	IPv4_get_frgmnt_num
760
	mov	dx, ax
761
	pop	ax
762
	shl	edx, 16
763
	mov	dh , [esi + ICMP_Packet.Type]
764
	mov	dl , [esi + ICMP_Packet.Code]
765
	mov	di , [esi + ICMP_Packet.Identifier]
766
;        mov     [eax + SOCKET.LocalPort], di            ; Set localport to the identifier number, so we can receive reply's
767
	shl	edi, 16
768
	mov	di , [esi + ICMP_Packet.SequenceNumber]
769
	add	esi, ICMP_Packet.Data
770
	mov	ebx, [eax + SOCKET.LocalIP]
771
	mov	eax, [eax + SOCKET.RemoteIP]
1196 hidnplayr 772
	call	ICMP_create_packet
1159 hidnplayr 773
 
774
	mov	[esp+32], eax
775
	ret
776
 
777
  .tcp:
778
 
779
	ret
780
 
781
 
782
 
783
 
784
 
785
 
786
 
787
 
788
; Allocate memory for socket data and put new socket into the list
789
; Newly created socket is initialized with calling PID and number and
790
; put into beginning of list (which is a fastest way).
791
;
792
; @return socket structure address in EAX
793
;
794
proc net_socket_alloc stdcall uses ebx ecx edx edi
795
	stdcall kernel_alloc, SOCKETBUFFSIZE
796
	DEBUGF	1, "K : net_socket_alloc (0x%x)\n", eax
797
	; check if we can allocate needed amount of memory
798
	or	eax, eax
799
	jz	.exit
800
 
801
	; zero-initialize allocated memory
802
	push	eax
803
	mov	edi, eax
804
	mov	ecx, SOCKETBUFFSIZE / 4
805
;        cld
806
	xor	eax, eax
807
	rep	stosd
808
	pop	eax
809
 
810
	; add socket to the list by changing pointers
811
	mov	ebx, net_sockets
812
	push	[ebx + SOCKET.NextPtr]
813
	mov	[ebx + SOCKET.NextPtr], eax
814
	mov	[eax + SOCKET.PrevPtr], ebx
815
	pop	ebx
816
	mov	[eax + SOCKET.NextPtr], ebx
817
	or	ebx, ebx
818
	jz	@f
819
	mov	[ebx + SOCKET.PrevPtr], eax
820
 
821
    @@: ; set socket owner PID to the one of calling process
822
	mov	ebx, [TASK_BASE]
823
	mov	ebx, [ebx + TASKDATA.pid]
824
	mov	[eax + SOCKET.PID], ebx
825
 
826
	; find first free socket number and use it
827
	;mov     edx, ebx
828
	mov	ebx, net_sockets
829
	xor	ecx, ecx
830
  .next_socket_number:
831
	inc	ecx
832
  .next_socket:
833
	mov	ebx, [ebx + SOCKET.NextPtr]
834
	or	ebx, ebx
835
	jz	.last_socket_number
836
	cmp	[ebx + SOCKET.Number], ecx
837
	jne	.next_socket
838
	;cmp     [ebx + SOCKET.PID], edx
839
	;jne     .next_socket
840
	mov	ebx, net_sockets
841
	jmp	.next_socket_number
842
 
843
  .last_socket_number:
844
	mov	[eax + SOCKET.Number], ecx
845
 
846
  .exit:
847
	ret
848
endp
849
 
850
; Free socket data memory and pop socket off the list
851
;
852
; @param sockAddr is a socket structure address
853
;
854
proc net_socket_free stdcall uses ebx ecx edx, sockAddr:DWORD
855
	mov	eax, [sockAddr]
856
	DEBUGF	1, "K : net_socket_free (0x%x)\n", eax
857
	; check if we got something similar to socket structure address
858
	or	eax, eax
859
	jz	.error
860
 
861
	; make sure sockAddr is one of the socket addresses in the list
862
	mov	ebx, net_sockets
863
	;mov     ecx, [TASK_BASE]
864
	;mov     ecx, [ecx + TASKDATA.pid]
865
  .next_socket:
866
	mov	ebx, [ebx + SOCKET.NextPtr]
867
	or	ebx, ebx
868
	jz	.error
869
	cmp	ebx, eax
870
	jne	.next_socket
871
	;cmp     [ebx + SOCKET.PID], ecx
872
	;jne     .next_socket
873
 
874
	; okay, we found the correct one
875
	; remove it from the list first, changing pointers
876
	mov	ebx, [eax + SOCKET.NextPtr]
877
	mov	eax, [eax + SOCKET.PrevPtr]
878
	mov	[eax + SOCKET.NextPtr], ebx
879
	or	ebx, ebx
880
	jz	@f
881
	mov	[ebx + SOCKET.PrevPtr], eax
882
 
883
    @@: ; and finally free the memory structure used
884
	stdcall kernel_free, [sockAddr]
885
	ret
886
 
887
  .error:
888
	DEBUGF	1, "K :   failed\n"
889
	ret
890
endp
891
 
892
; Get socket structure address by its number
893
; Scan through sockets list to find the socket with specified number.
894
; This proc uses SOCKET.PID indirectly to check if socket is owned by
895
; calling process.
896
;
897
; @param sockNum is a socket number
898
; @return socket structure address or 0 (not found) in EAX
899
;
900
proc net_socket_num_to_addr stdcall uses ebx ecx, sockNum:DWORD
901
	mov	eax, [sockNum]
902
	; check if we got something similar to socket number
903
	or	eax, eax
904
	jz	.error
905
 
906
	; scan through sockets list
907
	mov	ebx, net_sockets
908
	;mov     ecx, [TASK_BASE]
909
	;mov     ecx, [ecx + TASKDATA.pid]
910
  .next_socket:
911
	mov	ebx, [ebx + SOCKET.NextPtr]
912
	or	ebx, ebx
913
	jz	.error
914
	cmp	[ebx + SOCKET.Number], eax
915
	jne	.next_socket
916
	;cmp     [ebx + SOCKET.PID], ecx
917
	;jne     .next_socket
918
 
919
	; okay, we found the correct one
920
	mov	eax, ebx
921
	ret
922
 
923
  .error:
924
	xor	eax, eax
925
	ret
926
endp
927
 
928
; Get socket number by its structure address
929
; Scan through sockets list to find the socket with specified address.
930
; This proc uses SOCKET.PID indirectly to check if socket is owned by
931
; calling process.
932
;
933
; @param sockAddr is a socket structure address
934
; @return socket number (SOCKET.Number) or 0 (not found) in EAX
935
;
936
proc net_socket_addr_to_num stdcall uses ebx ecx, sockAddr:DWORD
937
	mov	eax, [sockAddr]
938
	; check if we got something similar to socket structure address
939
	or	eax, eax
940
	jz	.error
941
 
942
	; scan through sockets list
943
	mov	ebx, net_sockets
944
	;mov     ecx, [TASK_BASE]
945
	;mov     ecx, [ecx + TASKDATA.pid]
946
  .next_socket:
947
	mov	ebx, [ebx + SOCKET.NextPtr]
948
	or	ebx, ebx
949
	jz	.error
950
	cmp	ebx, eax
951
	jne	.next_socket
952
	;cmp     [ebx + SOCKET.PID], ecx
953
	;jne     .next_socket
954
 
955
	; okay, we found the correct one
956
	mov	eax, [ebx + SOCKET.Number]
957
	ret
958
 
959
  .error:
960
	xor	eax, eax
961
	ret
962
endp