Subversion Repositories Kolibri OS

Rev

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