Subversion Repositories Kolibri OS

Rev

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

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