Subversion Repositories Kolibri OS

Rev

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

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