Subversion Repositories Kolibri OS

Rev

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

Rev Author Line No. Line
431 serge 1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2
;;                                                              ;;
3
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;;
4
;; Distributed under terms of the GNU General Public License    ;;
5
;;                                                              ;;
6
;;  SOCKET.INC                                                  ;;
7
;;                                                              ;;
8
;;  Sockets constants, structures and functions                 ;;
9
;;                                                              ;;
10
;;  Last revision: 11.11.2006                                   ;;
11
;;                                                              ;;
12
;;  This file contains the following:                           ;;
13
;;    is_localport_unused                                       ;;
14
;;    get_free_socket                                           ;;
15
;;    socket_open                                               ;;
16
;;    socket_open_tcp                                           ;;
17
;;    socket_close                                              ;;
18
;;    socket_close_tcp                                          ;;
19
;;    socket_poll                                               ;;
20
;;    socket_status                                             ;;
21
;;    socket_read                                               ;;
22
;;    socket_write                                              ;;
23
;;    socket_write_tcp                                          ;;
24
;;                                                              ;;
25
;;                                                              ;;
26
;;  Changes history:                                            ;;
27
;;   22.09.2003 - [Mike Hibbett] : mikeh@oceanfree.net          ;;
28
;;   11.11.2006 - [Johnny_B] and [smb]                          ;;
29
;;                                                              ;;
30
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
261 hidnplayr 31
 
593 mikedld 32
$Revision: 738 $
33
 
34
 
261 hidnplayr 35
;
36
;  Socket Descriptor + Buffer
37
;
38
;    0                   1                   2                   3
39
;    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
40
;
41
;   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
42
;  0|                    Status ( of this buffer )                  |
43
;   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
44
;  4|  Application Process ID                                       |
45
;   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
46
;  8|                  Local IP Address                             |
47
;   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
48
; 12| Local IP Port                 | Unused ( set to 0 )           |
49
;   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
50
; 16|                  Remote IP Address                            |
51
;   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
52
; 20| Remote IP Port                | Unused ( set to 0 )           |
53
;   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
54
; 24|   Rx Data Count                                   INTEL format|
55
;   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
56
; 28|                 TCB STATE                         INTEL format|
57
;   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
58
; 32|   TCB Timer (seconds)                             INTEL format|
59
;   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
60
; 36| ISS (Inital Sequence # used by this connection )   INET format|
61
;   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
62
; 40| IRS ( Inital Receive Sequence # )                  INET format|
63
;   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
64
; 44| SND.UNA  Seq # of unack'ed sent packets            INET format|
65
;   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
66
; 48| SND.NXT  Next send seq # to use                    INET format|
67
;   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
68
; 52| SND.WND  Send window                               INET format|
69
;   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
70
; 56| RCV.NXT  Next expected receive sequence #          INET format|
71
;   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
72
; 60| RCV.WND  Receive window                            INET format|
73
;   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
74
; 64| SEG.LEN  Segment length                           INTEL format|
75
;   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
76
; 68| SEG.WND  Segment window                           INTEL format|
77
;   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
78
; 72| Retransmit queue # NOW WINDOW SIZE TIMER          INTEL format|
79
;   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
379 serge 80
; 76|      RX offset from
261 hidnplayr 81
; 76|       RX Data                                                 |
82
;   +-+-+-..........                                               -+
83
 
84
 
85
; so, define struct
86
struc SOCKET
379 serge 87
{  .Status		    dd	 ?  ;+00 - Status ( of this buffer )
88
   .PID 		    dd	 ?  ;+04 - Application Process ID
323 hidnplayr 89
   .LocalIP		    dd	 ?  ;+08 -  Local IP Address
90
   .LocalPort		    dw	 ?  ;+12 - Local Port
91
   .UnusedL		    dw	 ?  ;+14 - may be removed in future
92
   .RemoteIP		    dd	 ?  ;+16 - Remote IP Address
93
   .RemotePort		    dw	 ?  ;+20 - Remote Port
94
   .UnusedR		    dw	 ?  ;+22 - may be removed in future
95
   .rxDataCount 	    dd	 ?  ;+24 - Rx Data Count
96
   .TCBState		    dd	 ?  ;+28 - TCB STATE
379 serge 97
   .TCBTimer		    dd	 ?  ;+32 - TCB Timer (seconds)
323 hidnplayr 98
   .ISS 		    dd	 ?  ;+36 - Initial Send Sequence
99
   .IRS 		    dd	 ?  ;+40 - Initial Receive Sequence
100
   .SND_UNA		    dd	 ?  ;+44 - Sequence number of unack'ed sent packets
379 serge 101
   .SND_NXT		    dd	 ?  ;+48 - Next send sequence number to use
323 hidnplayr 102
   .SND_WND		    dd	 ?  ;+52 - Send window
103
   .RCV_NXT		    dd	 ?  ;+56 - Next receive sequence number to use
104
   .RCV_WND		    dd	 ?  ;+60 - Receive window
105
   .SEG_LEN		    dd	 ?  ;+64 - Segment length
106
   .SEG_WND		    dd	 ?  ;+68 - Segment window
379 serge 107
   .wndsizeTimer	    dd	 ?  ;+72 - Retransmit queue # NOW WINDOW SIZE TIMER
323 hidnplayr 108
   .rxData		    dd	 ?  ;+76 - receive data buffer here
261 hidnplayr 109
}
110
 
111
virtual at 0
112
  SOCKET SOCKET
113
end virtual
114
 
379 serge 115
; simple macro calcing real memory address of SOCKET struct by socket's
261 hidnplayr 116
macro	Index2RealAddr reg
117
{
323 hidnplayr 118
	shl	reg, 12
379 serge 119
    add     reg, sockets
261 hidnplayr 120
}
121
 
122
;Constants
123
; current socket statuses
323 hidnplayr 124
SOCK_EMPTY	   equ	   0	    ; socket not in use
125
SOCK_OPEN	   equ	   1	    ; open issued, but no data sent
261 hidnplayr 126
 
127
; TCP opening modes
323 hidnplayr 128
SOCKET_PASSIVE	   equ	   0
129
SOCKET_ACTIVE	   equ	   1
261 hidnplayr 130
 
131
;***************************************************************************
132
;   Function
133
;      is_localport_unused
134
;
135
;   Description
136
;         scans through all the active sockets , looking to see if the
137
;      port number specified in bx is in use as a localport number.
138
;      This is useful when you want a to generate a unique local port
139
;      number.
140
;          On return, eax = 1 for free, 0 for in use
141
;
142
;***************************************************************************
143
is_localport_unused:
144
    mov     al, bh
145
    mov     ah, bl
146
    mov     bx, ax
147
 
148
    mov     edx, SOCKETBUFFSIZE * NUM_SOCKETS
149
    mov     ecx, NUM_SOCKETS
323 hidnplayr 150
    mov     eax, 0		      ; Assume the return value is 'in use'
261 hidnplayr 151
 
152
ilu1:
153
    sub     edx, SOCKETBUFFSIZE
154
    cmp     [edx + sockets + SOCKET.LocalPort], bx
323 hidnplayr 155
    loopnz  ilu1		  ; Return back if the socket is occupied
261 hidnplayr 156
 
323 hidnplayr 157
    jz	    ilu_exit
158
    inc     eax 			; return port not in use
261 hidnplayr 159
 
160
ilu_exit:
161
    ret
162
 
163
 
164
 
165
;***************************************************************************
166
;   Function
167
;      get_free_socket
168
;
169
;   Description
170
;
171
;***************************************************************************
172
get_free_socket:
173
    push    ecx
174
    mov     eax, SOCKETBUFFSIZE * NUM_SOCKETS
175
    mov     ecx, NUM_SOCKETS
176
 
177
gfs1:
178
    sub     eax, SOCKETBUFFSIZE
179
    cmp     [eax + sockets + SOCKET.Status], dword SOCK_EMPTY
323 hidnplayr 180
    loopnz  gfs1		  ; Return back if the socket is occupied
261 hidnplayr 181
    mov     eax, ecx
182
    pop     ecx
323 hidnplayr 183
    jz	    gfs_exit
261 hidnplayr 184
    mov     eax, 0xFFFFFFFF
185
 
186
gfs_exit:
187
    ret
188
 
189
 
190
;***************************************************************************
191
;   Function
192
;      socket_open
193
;
194
;   Description
195
;       find a free socket
196
;       local port in ebx
197
;       remote port in ecx
198
;       remote ip in edx
199
;       return socket # in eax, -1 if none available
200
;
201
;***************************************************************************
202
socket_open:
203
    call    get_free_socket
204
 
205
    cmp     eax, 0xFFFFFFFF
323 hidnplayr 206
    jz	    so_exit
261 hidnplayr 207
 
208
    ; ax holds the socket number that is free. Get real address
209
    push    eax
210
    Index2RealAddr eax
211
 
212
    mov     [eax + SOCKET.Status], dword SOCK_OPEN
213
 
323 hidnplayr 214
    xchg    bh, bl
215
    mov     [eax + SOCKET.LocalPort], bx
216
    xchg    ch, cl
217
    mov     [eax + SOCKET.RemotePort], cx
261 hidnplayr 218
 
219
    mov     ebx, [stack_ip]
379 serge 220
    mov     [eax + SOCKET.LocalIP], ebx
221
    mov     [eax + SOCKET.RemoteIP], edx
261 hidnplayr 222
    mov     [eax + SOCKET.rxDataCount], dword 0      ; recieved data count
223
 
379 serge 224
    mov     esi, [TASK_BASE]
261 hidnplayr 225
    mov     ebx, [esi+TASKDATA.pid]
323 hidnplayr 226
    mov     [eax + SOCKET.PID], ebx	    ; save the process ID
261 hidnplayr 227
    pop     eax      ; Get the socket number back, so we can return it
228
 
229
so_exit:
230
    ret
231
 
232
 
233
 
234
;***************************************************************************
235
;   Function
236
;      socket_open_tcp
237
;
238
;   Description
239
;       Opens a TCP socket in PASSIVE or ACTIVE mode
240
;       find a free socket
241
;       local port in ebx ( intel format )
242
;       remote port in ecx ( intel format )
243
;       remote ip in edx ( in Internet byte order )
244
;       Socket open mode in esi  ( SOCKET_PASSIVE or SOCKET_ACTIVE )
245
;       return socket # in eax, -1 if none available
246
;
247
;***************************************************************************
248
socket_open_tcp:
249
    call    get_free_socket
250
 
251
    cmp     eax, 0xFFFFFFFF
323 hidnplayr 252
    jz	    so_exit
261 hidnplayr 253
 
254
    ; ax holds the socket number that is free. Get real address
255
    push eax
256
    Index2RealAddr eax
257
 
258
    mov     [sktAddr], eax
259
    mov     [eax], dword SOCK_OPEN
260
 
261
    ; TODO - check this works!
262
    mov     [eax + SOCKET.wndsizeTimer], dword 0     ; Reset the window timer.
263
 
323 hidnplayr 264
	xchg	bh, bl
379 serge 265
	mov	[eax + SOCKET.LocalPort], bx
261 hidnplayr 266
;    mov     [eax + 12], byte bh      ; Local port ( LS 16 bits )
267
;    mov     [eax + 13], byte bl      ; Local port ( LS 16 bits )
268
 
323 hidnplayr 269
	xchg	ch, cl
379 serge 270
	mov	[eax + SOCKET.RemotePort], cx
261 hidnplayr 271
;    mov     [eax + 20], ch         ; Remote Port ( LS 16 bits )
272
;    mov     [eax + 21], cl         ; Remote Port ( LS 16 bits )
273
 
274
    mov     ebx, [stack_ip]
379 serge 275
    mov     [eax + SOCKET.LocalIP], ebx
276
    mov     [eax + SOCKET.RemoteIP], edx
277
    mov     [eax + SOCKET.rxDataCount], dword 0
261 hidnplayr 278
 
279
    ; Now fill in TCB state
280
    mov     ebx, TCB_LISTEN
281
    cmp     esi, SOCKET_PASSIVE
323 hidnplayr 282
    jz	    sot_001
261 hidnplayr 283
    mov     ebx, TCB_SYN_SENT
284
 
285
sot_001:
323 hidnplayr 286
    mov     [eax + SOCKET.TCBState], ebx	    ; Indicate the state of the TCB
261 hidnplayr 287
 
379 serge 288
    mov     esi, [TASK_BASE]
261 hidnplayr 289
    mov     ecx, [esi+TASKDATA.pid]
323 hidnplayr 290
    mov     [eax + SOCKET.PID], ecx	    ; save the process ID
261 hidnplayr 291
 
292
    cmp     ebx, TCB_LISTEN
323 hidnplayr 293
    je	    sot_done
261 hidnplayr 294
 
295
    ; Now, if we are in active mode, then we have to send a SYN to the specified remote port
296
    mov     eax, EMPTY_QUEUE
297
    call    dequeue
298
    cmp     ax, NO_BUFFER
323 hidnplayr 299
    je	    sot_done
261 hidnplayr 300
 
301
    push    eax
302
 
323 hidnplayr 303
    mov     bl, 0x02	    ; SYN
261 hidnplayr 304
    mov     ecx, 0
305
 
306
    call    buildTCPPacket
307
 
308
    mov     eax, NET1OUT_QUEUE
309
 
310
    mov     edx, [stack_ip]
311
    mov     ecx, [sktAddr ]
312
    mov     ecx, [ecx + 16]
313
    cmp     edx, ecx
314
    jne     sot_notlocal
315
    mov     eax, IPIN_QUEUE
316
 
317
sot_notlocal:
318
       ; Send it.
319
    pop     ebx
320
    call    queue
321
 
322
    mov     esi, [sktAddr]
323
 
324
    ; increment SND.NXT in socket
325
    add     esi, 48
326
    call    inc_inet_esi
327
 
328
sot_done:
329
    pop     eax      ; Get the socket number back, so we can return it
330
 
331
sot_exit:
332
    ret
333
 
334
 
335
 
336
;***************************************************************************
337
;   Function
338
;      socket_close
339
;
340
;   Description
341
;       socket # in ebx
342
;       returns 0 for ok, -1 for socket not open (fail)
343
;
344
;***************************************************************************
345
socket_close:
738 diamond 346
    mov     eax, 0xFFFFFFFF	    ; assume this operation will fail..
347
    cmp     ebx, NUM_SOCKETS
348
    jae     sc_exit
261 hidnplayr 349
    Index2RealAddr ebx
350
    cmp     [ebx + SOCKET.Status], dword SOCK_EMPTY
323 hidnplayr 351
    jz	    sc_exit
261 hidnplayr 352
 
353
    ; Clear the socket varaibles
354
    xor     eax, eax
355
    mov     edi, ebx
356
    mov     ecx, SOCKETHEADERSIZE
357
    cld
358
    rep     stosb
359
 
360
sc_exit:
361
    ret
362
 
363
 
364
 
365
;***************************************************************************
366
;   Function
367
;      socket_close_tcp
368
;
369
;   Description
370
;       socket # in ebx
371
;       returns 0 for ok, -1 for socket not open (fail)
372
;
373
;***************************************************************************
374
socket_close_tcp:
375
    ; first, remove any resend entries
376
    pusha
377
 
378
    mov     esi, resendQ
379
    mov     ecx, 0
380
 
381
sct001:
382
    cmp     ecx, NUMRESENDENTRIES
323 hidnplayr 383
    je	    sct003		; None left
261 hidnplayr 384
    cmp     [esi], bl
323 hidnplayr 385
    je	    sct002		; found one
261 hidnplayr 386
    inc     ecx
387
    add     esi, 4
388
    jmp     sct001
389
 
390
sct002:
391
 
392
    mov     [esi], byte 0xFF
393
    jmp     sct001
394
 
395
sct003:
396
    popa
397
 
398
    Index2RealAddr ebx
399
    mov     [sktAddr], ebx
323 hidnplayr 400
    mov     eax, 0xFFFFFFFF	    ; assume this operation will fail..
261 hidnplayr 401
    cmp     [ebx + SOCKET.Status], dword SOCK_EMPTY
323 hidnplayr 402
    jz	    sct_exit
261 hidnplayr 403
 
404
    ; Now construct the response, and queue for sending by IP
405
    mov     eax, EMPTY_QUEUE
406
    call    dequeue
407
    cmp     ax, NO_BUFFER
323 hidnplayr 408
    je	    stl_exit
261 hidnplayr 409
 
410
    push    eax
411
 
323 hidnplayr 412
    mov     bl, 0x11	    ; FIN + ACK
261 hidnplayr 413
    mov     ecx, 0
414
    mov     esi, 0
415
 
416
    call    buildTCPPacket
417
 
418
    mov     ebx, [sktAddr]
419
 
420
    ; increament SND.NXT in socket
421
    mov     esi, 48
422
    add     esi, ebx
423
    call    inc_inet_esi
424
 
425
 
426
    ; Get the socket state
427
    mov     eax, [ebx + SOCKET.TCBState]
428
    cmp     eax, TCB_LISTEN
323 hidnplayr 429
    je	    destroyTCB
261 hidnplayr 430
    cmp     eax, TCB_SYN_SENT
323 hidnplayr 431
    je	    destroyTCB
261 hidnplayr 432
    cmp     eax, TCB_SYN_RECEIVED
323 hidnplayr 433
    je	    sct_finwait1
261 hidnplayr 434
    cmp     eax, TCB_ESTABLISHED
323 hidnplayr 435
    je	    sct_finwait1
261 hidnplayr 436
 
437
    ; assume CLOSE WAIT
438
    ; Send a fin, then enter last-ack state
439
    mov     eax, TCB_LAST_ACK
440
    mov     [ebx + SOCKET.TCBState], eax
441
    xor     eax, eax
442
    jmp     sct_send
443
 
444
sct_finwait1:
445
    ; Send a fin, then enter finwait2 state
446
    mov     eax, TCB_FIN_WAIT_1
447
    mov     [ebx + SOCKET.TCBState], eax
448
    xor     eax, eax
449
 
450
sct_send:
451
    mov     eax, NET1OUT_QUEUE
452
 
453
    mov     edx, [stack_ip]
454
    mov     ecx, [sktAddr ]
455
    mov     ecx, [ecx + 16]
456
    cmp     edx, ecx
457
    jne     sct_notlocal
458
    mov     eax, IPIN_QUEUE
459
 
460
sct_notlocal:
461
       ; Send it.
462
    pop     ebx
463
    call    queue
464
    jmp     sct_exit
465
 
466
destroyTCB:
467
    pop     eax
468
    ; Clear the socket varaibles
469
    xor     eax, eax
470
    mov     edi, ebx
471
    mov     ecx, SOCKETHEADERSIZE
472
    cld
473
    rep     stosb
474
 
475
sct_exit:
476
    ret
477
 
478
 
479
 
480
;***************************************************************************
481
;   Function
482
;      socket_poll
483
;
484
;   Description
485
;       socket # in ebx
486
;       returns count in eax.
487
;
488
;***************************************************************************
489
socket_poll:
490
    Index2RealAddr ebx
491
    mov     eax, [ebx + SOCKET.rxDataCount]
492
 
493
    ret
494
 
495
 
496
 
497
;***************************************************************************
498
;   Function
499
;      socket_status
500
;
501
;   Description
502
;       socket # in ebx
503
;       returns TCB state in eax.
504
;
505
;***************************************************************************
506
socket_status:
507
    Index2RealAddr ebx
508
    mov     eax, [ebx + SOCKET.TCBState]
509
 
510
    ret
511
 
512
 
513
 
514
;***************************************************************************
515
;   Function
516
;      socket_read
517
;
518
;   Description
519
;       socket # in ebx
520
;       returns # of bytes remaining in eax, data in bl
521
;
522
;***************************************************************************
523
socket_read:
524
    Index2RealAddr ebx
323 hidnplayr 525
    mov     eax, [ebx + SOCKET.rxDataCount]	    ; get count of bytes
261 hidnplayr 526
    mov     ecx, 1
527
    test    eax, eax
323 hidnplayr 528
    jz	    sr2
261 hidnplayr 529
 
530
    dec     eax
323 hidnplayr 531
    mov     esi, ebx		; esi is address of socket
532
    mov     [ebx + SOCKET.rxDataCount], eax	    ; store new count
261 hidnplayr 533
    ;movzx   ebx, byte [ebx + SOCKET.rxData]  ; get the byte
323 hidnplayr 534
    movzx   ebx, byte [ebx + SOCKETHEADERSIZE]	; get the byte
261 hidnplayr 535
    add     esi, SOCKETHEADERSIZE
536
    mov     edi, esi
537
    inc     esi
538
 
539
    mov     ecx, (SOCKETBUFFSIZE - SOCKETHEADERSIZE) / 4
540
    cld
541
    rep     movsd
542
    xor     ecx, ecx
543
 
544
sr1:
545
    jmp     sor_exit
546
 
547
sr2:
548
    xor     bl, bl
549
 
550
sor_exit:
551
    ret
552
 
553
 
323 hidnplayr 554
;***************************************************************************
555
;   Function
556
;      socket_read_packet
557
;
558
;   Description
559
;       socket # in ebx
560
;       datapointer # in ecx
561
;       buffer size in edx
562
;       returns # of bytes copied in eax
563
;
564
;***************************************************************************
565
socket_read_packet:
566
    Index2RealAddr ebx					   ; get real socket address
567
    mov     eax, [ebx + SOCKET.rxDataCount]		   ; get count of bytes
568
    test    eax, eax					   ; if count of bytes is zero..
569
    jz	    .exit					   ; exit function (eax will be zero)
261 hidnplayr 570
 
323 hidnplayr 571
    test    edx, edx					   ; if buffer size is zero, copy all data
572
    jz	    .copyallbytes
573
    cmp     edx, eax					   ; if buffer size is larger then the bytes of data, copy all data
574
    jge     .copyallbytes
575
 
576
    sub     eax, edx					   ; store new count (data bytes in buffer - bytes we're about to copy)
577
    mov     [ebx + SOCKET.rxDataCount], eax		   ;
578
    push    eax
579
    mov     eax, edx					   ; number of bytes we want to copy must be in eax
580
    call    .startcopy					   ; copy to the application
581
 
582
    mov     esi, ebx					   ; now we're going to copy the remaining bytes to the beginning
583
    add     esi, SOCKETHEADERSIZE			   ; we dont need to copy the header
584
    mov     edi, esi					   ; edi is where we're going to copy to
585
    add     esi, edx					   ; esi is from where we copy
586
    pop     ecx 					   ; count of bytes we have left
587
    push    ecx 					   ; push it again so we can re-use it later
588
    shr     ecx, 2					   ; divide eax by 4
589
    cld
590
    rep     movsd					   ; copy all full dwords
591
    pop     ecx
592
    and     ecx, 3
593
    rep     movsb					   ; copy remaining bytes
594
 
595
    ret 						   ; at last, exit
596
 
597
.copyallbytes:
598
    xor     esi, esi
599
    mov     [ebx + SOCKET.rxDataCount], esi		   ; store new count (zero)
600
 
601
.startcopy:
602
    mov     edi, ecx					   ;
465 serge 603
 ;   add     edi, std_application_base_address              ; get data pointer to buffer in application
323 hidnplayr 604
 
605
    mov     esi, ebx					   ;
606
    add     esi, SOCKETHEADERSIZE			   ; we dont need to copy the header
607
    mov     ecx, eax					   ; eax is count of bytes
608
    push    ecx
609
    shr     ecx, 2					   ; divide eax by 4
610
    cld 						   ; copy all full dwords
611
    rep     movsd					   ;
612
    pop     ecx
613
    and     ecx, 3
614
    rep     movsb					   ; copy the rest bytes
615
 
616
.exit:
617
    ret 						   ; exit, or go back to shift remaining bytes if any
618
 
619
 
620
 
621
 
261 hidnplayr 622
;***************************************************************************
623
;   Function
624
;      socket_write
625
;
626
;   Description
627
;       socket in ebx
628
;       # of bytes to write in ecx
629
;       pointer to data in edx
630
;       returns 0 in eax ok, -1 == failed ( invalid socket, or
631
;       could not queue IP packet )
632
;
633
;***************************************************************************
634
socket_write:
635
    Index2RealAddr ebx
636
 
637
    mov     eax, 0xFFFFFFFF
638
    ; If the socket is invalid, return with an error code
639
    cmp     [ebx], dword SOCK_EMPTY
323 hidnplayr 640
    je	    sw_exit
261 hidnplayr 641
 
642
 
643
    mov     eax, EMPTY_QUEUE
644
    call    dequeue
645
    cmp     ax, NO_BUFFER
323 hidnplayr 646
    je	    sw_exit
261 hidnplayr 647
 
648
    ; Save the queue entry number
649
    push    eax
650
 
651
    ; save the pointers to the data buffer & size
652
    push    edx
653
    push    ecx
654
 
655
    ; convert buffer pointer eax to the absolute address
656
    mov     ecx, IPBUFFSIZE
657
    mul     ecx
658
    add     eax, IPbuffs
659
 
660
    mov     edx, eax
661
 
662
    ; So, ebx holds the socket ptr, edx holds the IPbuffer ptr
663
 
664
    ; Fill in the IP header ( some data is in the socket descriptor)
665
    mov     eax, [ebx + 8]
323 hidnplayr 666
    mov     [edx + 12], eax	 ; source IP
261 hidnplayr 667
    mov     eax, [ebx + 16]
323 hidnplayr 668
    mov     [edx + 16], eax	 ; Destination IP
261 hidnplayr 669
 
670
    mov     al, 0x45
323 hidnplayr 671
    mov     [edx], al	      ; Version, IHL
261 hidnplayr 672
    xor     al, al
673
    mov     [edx + 1], al     ; Type of service
674
 
323 hidnplayr 675
    pop     eax 		  ; Get the UDP data length
261 hidnplayr 676
    push    eax
677
 
323 hidnplayr 678
    add     eax, 20 + 8 	  ; add IP header and UDP header lengths
261 hidnplayr 679
    mov     [edx + 2], ah
680
    mov     [edx + 3], al
681
    xor     al, al
682
    mov     [edx + 4], al
683
    mov     [edx + 5], al
684
    mov     al, 0x40
685
    mov     [edx + 6], al
686
    xor     al, al
687
    mov     [edx + 7], al
688
    mov     al, 0x20
689
    mov     [edx + 8], al
690
    mov     al, 17
691
    mov     [edx + 9], al
692
 
693
    ; Checksum left unfilled
694
    xor     ax, ax
695
    mov     [edx + 10], ax
696
 
697
    ; Fill in the UDP header ( some data is in the socket descriptor)
698
    mov     ax, [ebx + 12]
699
    mov     [edx + 20], ax
700
 
701
    mov     ax, [ebx + 20]
702
    mov     [edx + 20 + 2], ax
703
 
704
    pop     eax
705
    push    eax
706
 
707
    add     eax, 8
708
    mov     [edx + 20 + 4], ah
709
    mov     [edx + 20 + 5], al
710
 
711
    ; Checksum left unfilled
712
    xor     ax, ax
713
    mov     [edx + 20 + 6], ax
714
 
323 hidnplayr 715
    pop     ecx 		 ; count of bytes to send
716
    mov     ebx, ecx		; need the length later
717
    pop     eax 		 ; get callers ptr to data to send
261 hidnplayr 718
 
719
    ; Get the address of the callers data
379 serge 720
    mov     edi, [TASK_BASE]
261 hidnplayr 721
    add     edi, TASKDATA.mem_start
722
    add     eax, [edi]
723
    mov     esi, eax
724
 
725
    mov     edi, edx
726
    add     edi, 28
727
    cld
323 hidnplayr 728
    rep     movsb		; copy the data across
261 hidnplayr 729
 
730
    ; we have edx as IPbuffer ptr.
731
    ; Fill in the UDP checksum
732
    ; First, fill in pseudoheader
733
    mov     eax, [edx + 12]
734
    mov     [pseudoHeader], eax
735
    mov     eax, [edx + 16]
736
    mov     [pseudoHeader+4], eax
323 hidnplayr 737
    mov     ax, 0x1100		  ; 0 + protocol
261 hidnplayr 738
    mov     [pseudoHeader+8], ax
739
    add     ebx, 8
740
    mov     eax, ebx
741
    mov     [pseudoHeader+10], ah
742
    mov     [pseudoHeader+11], al
743
 
744
    mov     eax, pseudoHeader
745
    mov     [checkAdd1], eax
746
    mov     [checkSize1], word 12
747
    mov     eax, edx
748
    add     eax, 20
749
    mov     [checkAdd2], eax
750
    mov     eax, ebx
323 hidnplayr 751
    mov     [checkSize2], ax	  ; was eax!! mjh 8/7/02
261 hidnplayr 752
 
753
    call    checksum
754
 
755
    ; store it in the UDP checksum ( in the correct order! )
756
    mov     ax, [checkResult]
757
 
758
    ; If the UDP checksum computes to 0, we must make it 0xffff
759
    ; (0 is reserved for 'not used')
760
    cmp     ax, 0
761
    jne     sw_001
762
    mov     ax, 0xffff
763
 
764
sw_001:
765
    mov     [edx + 20 + 6], ah
766
    mov     [edx + 20 + 7], al
767
 
768
    ; Fill in the IP header checksum
323 hidnplayr 769
    GET_IHL ecx,edx		 ; get IP-Header length
261 hidnplayr 770
    stdcall checksum_jb,edx,ecx  ; buf_ptr, buf_size
771
 
772
    mov     [edx + 10], ah
773
    mov     [edx + 11], al
774
 
775
    ; Check destination IP address.
776
    ; If it is the local host IP, route it back to IP_RX
777
 
778
    pop     ebx
779
    mov     eax, NET1OUT_QUEUE
780
 
781
    mov     ecx, [ edx + 16]
782
    mov     edx, [stack_ip]
783
    cmp     edx, ecx
784
    jne     sw_notlocal
785
    mov     eax, IPIN_QUEUE
786
 
787
sw_notlocal:
788
    ; Send it.
789
    call    queue
790
 
791
    xor     eax, eax
792
 
793
sw_exit:
794
    ret
795
 
796
 
797
 
798
;***************************************************************************
799
;   Function
800
;      socket_write_tcp
801
;
802
;   Description
803
;       socket in ebx
804
;       # of bytes to write in ecx
805
;       pointer to data in edx
806
;       returns 0 in eax ok, -1 == failed ( invalid socket, or
807
;       could not queue IP packet )
808
;
809
;***************************************************************************
810
socket_write_tcp:
811
	Index2RealAddr ebx
812
 
813
    mov     [sktAddr], ebx
814
 
815
    mov     eax, 0xFFFFFFFF
816
    ; If the socket is invalid, return with an error code
817
    cmp     [ebx], dword SOCK_EMPTY
323 hidnplayr 818
    je	    swt_exit
261 hidnplayr 819
 
820
    ; If the sockets window timer is nonzero, do not queue packet
821
    ; TODO - done
822
    cmp     [ebx + SOCKET.wndsizeTimer], dword 0
823
    jne     swt_exit
824
 
825
    mov     eax, EMPTY_QUEUE
826
    call    dequeue
827
    cmp     ax, NO_BUFFER
323 hidnplayr 828
    je	    swt_exit
261 hidnplayr 829
 
830
    push    eax
831
 
323 hidnplayr 832
    mov     bl, 0x10	    ; ACK
261 hidnplayr 833
 
834
    ; Get the address of the callers data
379 serge 835
    mov     edi, [TASK_BASE]
261 hidnplayr 836
    add     edi, TASKDATA.mem_start
837
    add     edx, [edi]
838
    mov     esi, edx
839
 
840
    pop     eax
841
    push    eax
842
 
843
    push    ecx
844
    call    buildTCPPacket
845
    pop     ecx
846
 
847
    ; Check destination IP address.
848
    ; If it is the local host IP, route it back to IP_RX
849
 
850
    pop     ebx
851
    push    ecx
852
    mov     eax, NET1OUT_QUEUE
853
 
854
    mov     edx, [stack_ip]
855
    mov     ecx, [sktAddr ]
856
    mov     ecx, [ecx + 16]
857
    cmp     edx, ecx
858
    jne     swt_notlocal
859
    mov     eax, IPIN_QUEUE
860
 
861
swt_notlocal:
862
    pop     ecx
863
 
323 hidnplayr 864
    push    ebx 		; save ipbuffer number
261 hidnplayr 865
 
866
    call    queue
867
 
868
    mov     esi, [sktAddr]
869
 
870
    ; increament SND.NXT in socket
871
    ; Amount to increment by is in ecx
872
    add     esi, 48
873
    call    add_inet_esi
874
 
875
    pop     ebx
876
 
877
    ; Copy the IP buffer to a resend queue
878
    ; If there isn't one, dont worry about it for now
879
    mov     esi, resendQ
880
    mov     ecx, 0
881
 
882
swt003:
883
    cmp     ecx, NUMRESENDENTRIES
323 hidnplayr 884
    je	    swt001		; None found
261 hidnplayr 885
    cmp     [esi], byte 0xFF
323 hidnplayr 886
    je	    swt002		; found one
261 hidnplayr 887
    inc     ecx
888
    add     esi, 4
889
    jmp     swt003
890
 
891
swt002:
892
    push    ebx
893
 
894
    ; OK, we have a buffer descriptor ptr in esi.
895
    ; resend entry # in ecx
896
    ;  Populate it
897
    ;  socket #
898
    ;  retries count
899
    ;  retry time
900
    ;  fill IP buffer associated with this descriptor
901
 
902
    mov     eax, [sktAddr]
903
    sub     eax, sockets
323 hidnplayr 904
    shr     eax, 12		; get skt #
261 hidnplayr 905
    mov     [esi], al
906
    mov     [esi + 1], byte TCP_RETRIES
907
    mov     [esi + 2], word TCP_TIMEOUT
908
 
909
    inc     ecx
910
    ; Now get buffer location, and copy buffer across. argh! more copying,,
911
    mov     edi, resendBuffer - IPBUFFSIZE
912
swt002a:
913
    add     edi, IPBUFFSIZE
914
    loop    swt002a
915
 
916
    ; we have dest buffer location in edi
917
    pop     eax
918
    ; convert source buffer pointer eax to the absolute address
919
    mov     ecx, IPBUFFSIZE
920
    mul     ecx
921
    add     eax, IPbuffs
922
    mov     esi, eax
923
 
924
    ; do copy
925
    mov     ecx, IPBUFFSIZE
926
    cld
927
    rep     movsb
928
 
929
swt001:
930
    xor     eax, eax
931
 
932
swt_exit:
933
    ret
934