Subversion Repositories Kolibri OS

Rev

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