Subversion Repositories Kolibri OS

Rev

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

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