Subversion Repositories Kolibri OS

Rev

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