Subversion Repositories Kolibri OS

Rev

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