Subversion Repositories Kolibri OS

Rev

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

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