Subversion Repositories Kolibri OS

Rev

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