Subversion Repositories Kolibri OS

Rev

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