Subversion Repositories Kolibri OS

Rev

Rev 2888 | 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: 2890 $
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
 
135
        sendalot                db ?
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
 
2402 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
 
2402 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
        DEBUGF  1,"af_inet4\n"
1514 hidnplayr 389
 
2402 hidnplayr 390
        cmp     esi, 6
391
        jb      s_error
1159 hidnplayr 392
 
2622 hidnplayr 393
        cmp     [eax + SOCKET.Protocol], IP_PROTO_UDP
394
        je      .udp
1159 hidnplayr 395
 
2622 hidnplayr 396
        cmp     [eax + SOCKET.Protocol], IP_PROTO_TCP
397
        je      .tcp
1159 hidnplayr 398
 
2622 hidnplayr 399
        jmp     s_error
400
 
401
  .tcp:
402
  .udp:
403
 
404
        mov     ebx, [edx + 4]                  ; First, fill in the IP
405
        test    ebx, ebx                        ; If IP is 0, use default
406
        jnz     @f
407
        mov     ebx, [NET_DEFAULT]
408
        mov     ebx, [IP_LIST + 4*ebx]
409
       @@:
410
        mov     [eax + IP_SOCKET.LocalIP], ebx
411
 
412
        mov     bx, [edx + 2]                   ; Now fill in the port if it's still available
413
        call    SOCKET_check_port
414
        jz      s_error                         ; ZF is set by socket_check_port, on error
415
 
2402 hidnplayr 416
        DEBUGF  1,"local ip: %u.%u.%u.%u\n",\
417
        [eax + IP_SOCKET.LocalIP + 0]:1,[eax + IP_SOCKET.LocalIP + 1]:1,\
418
        [eax + IP_SOCKET.LocalIP + 2]:1,[eax + IP_SOCKET.LocalIP + 3]:1
1159 hidnplayr 419
 
2402 hidnplayr 420
        mov     dword [esp+32], 0
421
        ret
1159 hidnplayr 422
 
423
 
424
 
425
 
1257 hidnplayr 426
;-----------------------------------------------------------------
1159 hidnplayr 427
;
428
; SOCKET_connect
429
;
430
;  IN:  socket number in ecx
431
;       pointer to sockaddr struct in edx
432
;       length of that struct in esi
433
;  OUT: 0 on success
434
;
1257 hidnplayr 435
;-----------------------------------------------------------------
1159 hidnplayr 436
align 4
1514 hidnplayr 437
SOCKET_connect:
1159 hidnplayr 438
 
2402 hidnplayr 439
        DEBUGF  1,"SOCKET_connect: socknum: %u sockaddr: %x, length: %u\n", ecx, edx, esi
1159 hidnplayr 440
 
2402 hidnplayr 441
        call    SOCKET_num_to_ptr
442
        jz      s_error
1159 hidnplayr 443
 
2402 hidnplayr 444
        cmp     esi, 8
445
        jb      s_error
1159 hidnplayr 446
 
2402 hidnplayr 447
        cmp     word [edx], AF_INET4
448
        je      .af_inet4
1159 hidnplayr 449
 
2402 hidnplayr 450
        jmp     s_error
1159 hidnplayr 451
 
452
  .af_inet4:
2402 hidnplayr 453
        cmp     [eax + IP_SOCKET.LocalIP], 0
454
        jne     @f
455
        push    [IP_LIST]
456
        pop     [eax + IP_SOCKET.LocalIP]
1543 hidnplayr 457
       @@:
1159 hidnplayr 458
 
2402 hidnplayr 459
        cmp     [eax + SOCKET.Protocol], IP_PROTO_UDP
460
        je      .udp
1159 hidnplayr 461
 
2402 hidnplayr 462
        cmp     [eax + SOCKET.Protocol], IP_PROTO_TCP
463
        je      .tcp
1159 hidnplayr 464
 
2402 hidnplayr 465
        cmp     [eax + SOCKET.Protocol], IP_PROTO_IP
466
        je      .ip
1541 hidnplayr 467
 
2402 hidnplayr 468
        cmp     [eax + SOCKET.Protocol], IP_PROTO_ICMP
469
        je      .ip
1542 hidnplayr 470
 
2402 hidnplayr 471
        jmp     s_error
1159 hidnplayr 472
 
1542 hidnplayr 473
align 4
1254 hidnplayr 474
  .udp:
2402 hidnplayr 475
        pusha
476
        lea     ecx, [eax + SOCKET.mutex]
477
        call    mutex_lock
478
        popa
1543 hidnplayr 479
 
2402 hidnplayr 480
        pushw   [edx + 2]
481
        pop     [eax + UDP_SOCKET.RemotePort]
1543 hidnplayr 482
 
2402 hidnplayr 483
        pushd   [edx + 4]
484
        pop     [eax + IP_SOCKET.RemoteIP]
1543 hidnplayr 485
 
2402 hidnplayr 486
        cmp     [eax + UDP_SOCKET.LocalPort], 0
487
        jne     @f
488
        call    SOCKET_find_port
1543 hidnplayr 489
       @@:
490
 
2402 hidnplayr 491
        mov     [eax + UDP_SOCKET.firstpacket], 0
1159 hidnplayr 492
 
2402 hidnplayr 493
        push    eax
494
        init_queue (eax + SOCKET_QUEUE_LOCATION)        ; Set up data receiving queue
495
        pop     eax
1159 hidnplayr 496
 
2402 hidnplayr 497
        lea     ecx, [eax + SOCKET.mutex]
498
        call    mutex_unlock
1159 hidnplayr 499
 
2402 hidnplayr 500
        mov     dword [esp+32], 0
501
        ret
502
 
1542 hidnplayr 503
align 4
1254 hidnplayr 504
  .tcp:
2402 hidnplayr 505
        pusha
506
        lea     ecx, [eax + SOCKET.mutex]
507
        call    mutex_lock
508
        popa
1159 hidnplayr 509
 
2402 hidnplayr 510
        pushw   [edx + 2]
511
        pop     [eax + TCP_SOCKET.RemotePort]
1159 hidnplayr 512
 
2402 hidnplayr 513
        pushd   [edx + 4]
514
        pop     [eax + IP_SOCKET.RemoteIP]
1159 hidnplayr 515
 
2402 hidnplayr 516
        cmp     [eax + TCP_SOCKET.LocalPort], 0
517
        jne     @f
518
        call    SOCKET_find_port
1543 hidnplayr 519
       @@:
1159 hidnplayr 520
 
2402 hidnplayr 521
        mov     [eax + TCP_SOCKET.timer_persist], 0
522
        mov     [eax + TCP_SOCKET.t_state], TCPS_SYN_SENT
2612 hidnplayr 523
 
2402 hidnplayr 524
        push    [TCP_sequence_num]
525
        add     [TCP_sequence_num], 6400
526
        pop     [eax + TCP_SOCKET.ISS]
527
        mov     [eax + TCP_SOCKET.timer_keepalive], TCP_time_keep_init
1519 hidnplayr 528
 
2612 hidnplayr 529
 
2402 hidnplayr 530
        TCP_sendseqinit eax
1529 hidnplayr 531
 
1543 hidnplayr 532
;        mov     [ebx + TCP_SOCKET.timer_retransmission],   ;; todo: create macro to set retransmission timer
1533 hidnplayr 533
 
2402 hidnplayr 534
        mov     ebx, eax
1159 hidnplayr 535
 
2402 hidnplayr 536
        lea     eax, [ebx + STREAM_SOCKET.snd]
537
        call    SOCKET_ring_create
1543 hidnplayr 538
 
2402 hidnplayr 539
        lea     eax, [ebx + STREAM_SOCKET.rcv]
540
        call    SOCKET_ring_create
1543 hidnplayr 541
 
2402 hidnplayr 542
        pusha
2403 hidnplayr 543
        lea     ecx, [eax + SOCKET.mutex]
2402 hidnplayr 544
        call    mutex_unlock
545
        popa
1733 hidnplayr 546
 
2402 hidnplayr 547
        mov     eax, ebx
548
        call    TCP_output
1733 hidnplayr 549
 
2402 hidnplayr 550
        mov     dword [esp+32], 0
551
        ret
1159 hidnplayr 552
 
1542 hidnplayr 553
align 4
554
  .ip:
2402 hidnplayr 555
        pusha
556
        lea     ecx, [eax + SOCKET.mutex]
557
        call    mutex_lock
558
        popa
1543 hidnplayr 559
 
2402 hidnplayr 560
        pushd   [edx + 4]
561
        pop     [eax + IP_SOCKET.RemoteIP]
1159 hidnplayr 562
 
2402 hidnplayr 563
        push    eax
564
        init_queue (eax + SOCKET_QUEUE_LOCATION)        ; Set up data receiving queue
565
        pop     eax
1543 hidnplayr 566
 
2402 hidnplayr 567
        lea     ecx, [eax + SOCKET.mutex]
568
        call    mutex_unlock
1541 hidnplayr 569
 
2402 hidnplayr 570
        mov     dword [esp+32], 0
571
        ret
1541 hidnplayr 572
 
2402 hidnplayr 573
 
1257 hidnplayr 574
;-----------------------------------------------------------------
1159 hidnplayr 575
;
576
; SOCKET_listen
577
;
578
;  IN:  socket number in ecx
579
;       backlog in edx
580
;  OUT: eax is socket num, -1 on error
581
;
1257 hidnplayr 582
;-----------------------------------------------------------------
1206 hidnplayr 583
align 4
1514 hidnplayr 584
SOCKET_listen:
1159 hidnplayr 585
 
2402 hidnplayr 586
        DEBUGF  1,"SOCKET_listen: socknum: %u backlog: %u\n", ecx, edx
1159 hidnplayr 587
 
2402 hidnplayr 588
        call    SOCKET_num_to_ptr
589
        jz      s_error
1159 hidnplayr 590
 
2402 hidnplayr 591
        cmp     [eax + SOCKET.Domain], AF_INET4
592
        jne     s_error
1254 hidnplayr 593
 
2402 hidnplayr 594
        cmp     [eax + SOCKET.Protocol], IP_PROTO_TCP
595
        jne     s_error
1254 hidnplayr 596
 
2402 hidnplayr 597
        cmp     [eax + TCP_SOCKET.LocalPort], 0
598
        je      s_error
1514 hidnplayr 599
 
2402 hidnplayr 600
        cmp     [eax + IP_SOCKET.LocalIP], 0
601
        jne     @f
602
        push    [IP_LIST]
603
        pop     [eax + IP_SOCKET.LocalIP]
1543 hidnplayr 604
       @@:
605
 
2402 hidnplayr 606
        cmp     edx, MAX_backlog
607
        jbe     @f
608
        mov     edx, MAX_backlog
1543 hidnplayr 609
       @@:
1159 hidnplayr 610
 
2402 hidnplayr 611
        mov     [eax + SOCKET.backlog], dx
612
        or      [eax + SOCKET.options], SO_ACCEPTCON
613
        mov     [eax + TCP_SOCKET.t_state], TCPS_LISTEN
2880 hidnplayr 614
        mov     [eax + TCP_SOCKET.timer_keepalive], 0           ; disable keepalive timer
1159 hidnplayr 615
 
2402 hidnplayr 616
        push    eax
617
        init_queue (eax + SOCKET_QUEUE_LOCATION)                ; Set up sockets queue
618
        pop     eax
1543 hidnplayr 619
 
2402 hidnplayr 620
        mov     dword [esp+32], 0
1514 hidnplayr 621
 
2402 hidnplayr 622
        ret
1159 hidnplayr 623
 
624
 
1257 hidnplayr 625
;-----------------------------------------------------------------
1159 hidnplayr 626
;
627
; SOCKET_accept
628
;
629
;  IN:  socket number in ecx
630
;       addr in edx
631
;       addrlen in esi
632
;  OUT: eax is socket num, -1 on error
633
;
1257 hidnplayr 634
;-----------------------------------------------------------------
1206 hidnplayr 635
align 4
1514 hidnplayr 636
SOCKET_accept:
1159 hidnplayr 637
 
2402 hidnplayr 638
        DEBUGF  1,"SOCKET_accept: socknum: %u sockaddr: %x, length: %u\n", ecx, edx, esi
1159 hidnplayr 639
 
2402 hidnplayr 640
        call    SOCKET_num_to_ptr
641
        jz      s_error
1159 hidnplayr 642
 
2402 hidnplayr 643
        test    [eax + SOCKET.options], SO_ACCEPTCON
644
        jz      s_error
1543 hidnplayr 645
 
2402 hidnplayr 646
        cmp     [eax + SOCKET.Domain], AF_INET4
647
        jne     s_error
1249 hidnplayr 648
 
2402 hidnplayr 649
        cmp     [eax + SOCKET.Protocol], IP_PROTO_TCP
650
        jne     s_error
1249 hidnplayr 651
 
2402 hidnplayr 652
        get_from_queue (eax + SOCKET_QUEUE_LOCATION), MAX_backlog, 4, s_error
2572 hidnplayr 653
        mov     eax, [esi]
1249 hidnplayr 654
 
2572 hidnplayr 655
; Change PID to that of the current process
656
        mov     ebx, [TASK_BASE]
657
        mov     ebx, [ebx + TASKDATA.pid]
658
        mov     [eax + SOCKET.PID], ebx
659
 
2402 hidnplayr 660
        call    SOCKET_ptr_to_num
661
        jz      s_error
662
        mov     [esp+32], eax
663
        ret
1514 hidnplayr 664
 
1159 hidnplayr 665
 
1257 hidnplayr 666
;-----------------------------------------------------------------
1159 hidnplayr 667
;
668
; SOCKET_close
669
;
670
;  IN:  socket number in ecx
671
;  OUT: eax is socket num, -1 on error
672
;
1257 hidnplayr 673
;-----------------------------------------------------------------
1206 hidnplayr 674
align 4
1514 hidnplayr 675
SOCKET_close:
1159 hidnplayr 676
 
2402 hidnplayr 677
        DEBUGF  1,"SOCKET_close: socknum: %u\n", ecx
1159 hidnplayr 678
 
2402 hidnplayr 679
        call    SOCKET_num_to_ptr
680
        jz      s_error
1159 hidnplayr 681
 
2402 hidnplayr 682
        cmp     [eax + SOCKET.Domain], AF_INET4
683
        jne     s_error
1159 hidnplayr 684
 
2402 hidnplayr 685
        cmp     [eax + SOCKET.Protocol], IP_PROTO_UDP
686
        je      .free
1159 hidnplayr 687
 
2402 hidnplayr 688
        cmp     [eax + SOCKET.Protocol], IP_PROTO_ICMP
689
        je      .free
1159 hidnplayr 690
 
2402 hidnplayr 691
        cmp     [eax + SOCKET.Protocol], IP_PROTO_IP
692
        je      .free
1542 hidnplayr 693
 
2402 hidnplayr 694
        cmp     [eax + SOCKET.Protocol], IP_PROTO_TCP
695
        je      .tcp
1159 hidnplayr 696
 
2402 hidnplayr 697
        jmp     s_error
1159 hidnplayr 698
 
699
  .tcp:
2402 hidnplayr 700
        cmp     [eax + TCP_SOCKET.t_state], TCPS_SYN_RECEIVED    ; state must be LISTEN, SYN_SENT or CLOSED
701
        jb      .free
1318 hidnplayr 702
 
2890 hidnplayr 703
        call    TCP_usrclosed
2402 hidnplayr 704
        mov     dword [esp+32], 0
1159 hidnplayr 705
 
2402 hidnplayr 706
        ret
1159 hidnplayr 707
 
1514 hidnplayr 708
  .free:
2402 hidnplayr 709
        call    SOCKET_free
710
        mov     dword [esp+32], 0
1159 hidnplayr 711
 
2402 hidnplayr 712
        ret
1159 hidnplayr 713
 
714
 
1257 hidnplayr 715
;-----------------------------------------------------------------
1159 hidnplayr 716
;
717
; SOCKET_receive
718
;
719
;  IN:  socket number in ecx
1249 hidnplayr 720
;       addr to buffer in edx
721
;       length of buffer in esi
1159 hidnplayr 722
;       flags in edi
723
;  OUT: eax is number of bytes copied, -1 on error
724
;
1257 hidnplayr 725
;-----------------------------------------------------------------
1206 hidnplayr 726
align 4
1514 hidnplayr 727
SOCKET_receive:
1159 hidnplayr 728
 
2402 hidnplayr 729
        DEBUGF  1,"SOCKET_receive: socknum: %u bufaddr: %x, buflength: %u, flags: %x, ", ecx, edx, esi, edi
1514 hidnplayr 730
 
2402 hidnplayr 731
        call    SOCKET_num_to_ptr
732
        jz      s_error
1159 hidnplayr 733
 
2402 hidnplayr 734
        jmp     [eax + SOCKET.rcv_proc]
1533 hidnplayr 735
 
1536 hidnplayr 736
 
737
align 4
1541 hidnplayr 738
SOCKET_receive_dgram:
1536 hidnplayr 739
 
2402 hidnplayr 740
        DEBUGF  1,"SOCKET_receive: DGRAM\n"
1536 hidnplayr 741
 
2402 hidnplayr 742
        mov     ebx, esi
743
        mov     edi, edx                                        ; addr to buffer
1159 hidnplayr 744
 
2402 hidnplayr 745
        get_from_queue (eax + SOCKET_QUEUE_LOCATION), SOCKET_QUEUE_SIZE, sizeof.socket_queue_entry, s_error       ; destroys esi and ecx
1536 hidnplayr 746
 
2402 hidnplayr 747
        mov     ecx, [esi + socket_queue_entry.data_size]
748
        DEBUGF  1,"Got %u bytes of data\n", ecx
1159 hidnplayr 749
 
2402 hidnplayr 750
        cmp     ecx, ebx
751
        ja      .too_small
1514 hidnplayr 752
 
2402 hidnplayr 753
        push    [esi + socket_queue_entry.buf_ptr]              ; save the buffer addr so we can clear it later
754
        mov     esi, [esi + socket_queue_entry.data_ptr]
755
        DEBUGF  1,"Source buffer: %x, real addr: %x\n", [esp], esi
756
        mov     [esp+32+4], ecx                                 ; return number of bytes copied
1159 hidnplayr 757
 
1514 hidnplayr 758
; copy the data
2402 hidnplayr 759
        shr     ecx, 1
760
        jnc     .nb
761
        movsb
1536 hidnplayr 762
  .nb:
2402 hidnplayr 763
        shr     ecx, 1
764
        jnc     .nw
765
        movsw
1536 hidnplayr 766
  .nw:
2402 hidnplayr 767
        test    ecx, ecx
768
        jz      .nd
769
        rep     movsd
1536 hidnplayr 770
  .nd:
1159 hidnplayr 771
 
2402 hidnplayr 772
        call    kernel_free                                     ; remove the packet
773
        ret
1514 hidnplayr 774
 
1536 hidnplayr 775
  .too_small:
1533 hidnplayr 776
 
2402 hidnplayr 777
        DEBUGF  1,"Buffer too small...\n"
778
        jmp     s_error
1536 hidnplayr 779
 
780
align 4
781
SOCKET_receive_tcp:
782
 
2402 hidnplayr 783
        DEBUGF  1,"SOCKET_receive: TCP\n"
1536 hidnplayr 784
 
2402 hidnplayr 785
        mov     ecx, esi
786
        mov     edi, edx
787
        add     eax, STREAM_SOCKET.rcv
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
 
2402 hidnplayr 811
        DEBUGF  1,"SOCKET_send: socknum: %u data ptr: %x, length: %u, flags: %x, ", 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
 
2402 hidnplayr 853
        DEBUGF  1,"type: IP\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
 
969
        DEBUGF  1,"Bound socket %x to device %x\n",eax, edx
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
 
2402 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
 
2402 hidnplayr 1087
        DEBUGF  1,"SOCKET_check_port\n"
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:
2402 hidnplayr 1111
        mov     [eax + UDP_SOCKET.LocalPort], bx
1112
        or      bx, bx                                  ; set the zero-flag
1514 hidnplayr 1113
 
2402 hidnplayr 1114
        ret
1206 hidnplayr 1115
 
1116
 
1257 hidnplayr 1117
 
1118
;-----------------------------------------------------------------
1206 hidnplayr 1119
;
1514 hidnplayr 1120
; SOCKET_input
1206 hidnplayr 1121
;
1536 hidnplayr 1122
; Updates a (stateless) socket with received data
1206 hidnplayr 1123
;
1514 hidnplayr 1124
; Note: the mutex should already be set !
1206 hidnplayr 1125
;
1249 hidnplayr 1126
;  IN:  eax = socket ptr
1514 hidnplayr 1127
;       ebx = pointer to device struct
1128
;       ecx = data size
1129
;       esi = ptr to data
1130
;       [esp] = ptr to buf
1131
;       [esp + 4] = buf size
1249 hidnplayr 1132
;
1514 hidnplayr 1133
;  OUT: /
1206 hidnplayr 1134
;
1257 hidnplayr 1135
;-----------------------------------------------------------------
1206 hidnplayr 1136
align 4
1514 hidnplayr 1137
SOCKET_input:
1206 hidnplayr 1138
 
2402 hidnplayr 1139
        DEBUGF  1,"SOCKET_input: socket=%x, data=%x size=%u\n", eax, esi, ecx
1206 hidnplayr 1140
 
2402 hidnplayr 1141
        mov     [esp+4], ecx
1142
        push    esi
1143
        mov     esi, esp
1514 hidnplayr 1144
 
2402 hidnplayr 1145
        add_to_queue (eax + SOCKET_QUEUE_LOCATION), SOCKET_QUEUE_SIZE, sizeof.socket_queue_entry, SOCKET_input.full
1514 hidnplayr 1146
 
2402 hidnplayr 1147
        DEBUGF  1,"SOCKET_input: queued packet successfully\n"
1148
        add     esp, sizeof.socket_queue_entry
1206 hidnplayr 1149
 
2402 hidnplayr 1150
        pusha
1151
        lea     ecx, [eax + SOCKET.mutex]
1152
        call    mutex_unlock
1153
        popa
1154
 
1155
        jmp     SOCKET_notify_owner
1156
 
1514 hidnplayr 1157
  .full:
2402 hidnplayr 1158
        DEBUGF  2,"SOCKET_input: socket %x is full!\n", eax
1206 hidnplayr 1159
 
2402 hidnplayr 1160
        pusha
1161
        lea     ecx, [eax + SOCKET.mutex]
1162
        call    mutex_unlock
1163
        popa
1514 hidnplayr 1164
 
2402 hidnplayr 1165
        call    kernel_free
1166
        add     esp, 8
1533 hidnplayr 1167
 
2402 hidnplayr 1168
        ret
1169
 
1170
 
1533 hidnplayr 1171
;--------------------------
1172
;
1173
; eax = ptr to ring struct (just a buffer of the right size)
1174
;
1175
align 4
1176
SOCKET_ring_create:
1177
 
2402 hidnplayr 1178
        push    esi
1179
        mov     esi, eax
1543 hidnplayr 1180
 
2402 hidnplayr 1181
        push    edx
1182
        stdcall create_ring_buffer, SOCKET_MAXDATA, PG_SW
1183
        pop     edx
1533 hidnplayr 1184
 
2402 hidnplayr 1185
        DEBUGF  1,"SOCKET_ring_created: %x\n", eax
1186
        mov     [esi + RING_BUFFER.start_ptr], eax
1187
        mov     [esi + RING_BUFFER.write_ptr], eax
1188
        mov     [esi + RING_BUFFER.read_ptr], eax
1189
        mov     [esi + RING_BUFFER.size], 0
2888 hidnplayr 1190
        add     eax, SOCKET_MAXDATA
2402 hidnplayr 1191
        mov     [esi + RING_BUFFER.end_ptr], eax
1192
        mov     eax, esi
1193
        pop     esi
1533 hidnplayr 1194
 
2402 hidnplayr 1195
        ret
1533 hidnplayr 1196
 
1514 hidnplayr 1197
;-----------------------------------------------------------------
1198
;
1533 hidnplayr 1199
; SOCKET_ring_write
1529 hidnplayr 1200
;
1533 hidnplayr 1201
; Adds data to a stream socket, and updates write pointer and size
1529 hidnplayr 1202
;
1203
;  IN:  eax = ptr to ring struct
1204
;       ecx = data size
1205
;       esi = ptr to data
1206
;
1533 hidnplayr 1207
;  OUT: ecx = number of bytes stored
1529 hidnplayr 1208
;
1209
;-----------------------------------------------------------------
1210
align 4
1533 hidnplayr 1211
SOCKET_ring_write:
1529 hidnplayr 1212
 
2402 hidnplayr 1213
        DEBUGF  1,"SOCKET_ring_write: ringbuff=%x ptr=%x size=%u\n", eax, esi, ecx
1529 hidnplayr 1214
 
2402 hidnplayr 1215
        add     [eax + RING_BUFFER.size], ecx
2573 hidnplayr 1216
        jc      .way_too_large
2402 hidnplayr 1217
        cmp     [eax + RING_BUFFER.size], SOCKET_MAXDATA
1218
        ja      .too_large
1529 hidnplayr 1219
 
1220
  .copy:
2402 hidnplayr 1221
        mov     edi, [eax + RING_BUFFER.write_ptr]
1222
        DEBUGF  2,"SOCKET_ring_write: %u bytes from %x to %x\n", ecx, esi, edi
1529 hidnplayr 1223
 
2402 hidnplayr 1224
        push    ecx
1225
        shr     ecx, 1
1226
        jnc     .nb
1227
        movsb
1536 hidnplayr 1228
  .nb:
2402 hidnplayr 1229
        shr     ecx, 1
1230
        jnc     .nw
1231
        movsw
1536 hidnplayr 1232
  .nw:
2402 hidnplayr 1233
        test    ecx, ecx
1234
        jz      .nd
1235
        rep     movsd
1536 hidnplayr 1236
  .nd:
2402 hidnplayr 1237
        pop     ecx
1529 hidnplayr 1238
 
2402 hidnplayr 1239
        cmp     edi, [eax + RING_BUFFER.end_ptr]
1240
        jae     .wrap
1241
        mov     [eax + RING_BUFFER.write_ptr], edi
1533 hidnplayr 1242
 
2402 hidnplayr 1243
        ret
1529 hidnplayr 1244
 
1533 hidnplayr 1245
  .wrap:
2402 hidnplayr 1246
        sub     edi, SOCKET_MAXDATA
1247
        mov     [eax + RING_BUFFER.write_ptr], edi
1533 hidnplayr 1248
 
2402 hidnplayr 1249
        ret
1533 hidnplayr 1250
 
2404 hidnplayr 1251
  .too_large:                                                           ; update size, we will fill buffer completely
1252
        sub     [eax + RING_BUFFER.size], SOCKET_MAXDATA
2402 hidnplayr 1253
        sub     ecx, [eax + RING_BUFFER.size]
2404 hidnplayr 1254
        mov     [eax + RING_BUFFER.size], SOCKET_MAXDATA
2573 hidnplayr 1255
        ja      .copy
1529 hidnplayr 1256
 
2573 hidnplayr 1257
  .full:
2402 hidnplayr 1258
        DEBUGF  2,"SOCKET_ring_write: ring buffer is full!\n"
1259
        xor     ecx, ecx
1260
        ret
1529 hidnplayr 1261
 
2573 hidnplayr 1262
  .way_too_large:
1263
        sub     [eax + RING_BUFFER.size], ecx
1264
        mov     ecx, SOCKET_MAXDATA
1265
        sub     ecx, [eax + RING_BUFFER.size]
1266
        ja      .copy
1267
        jmp     .full
1529 hidnplayr 1268
 
2573 hidnplayr 1269
 
1270
 
1529 hidnplayr 1271
;-----------------------------------------------------------------
1272
;
1273
; SOCKET_ring_read
1274
;
1533 hidnplayr 1275
; reads the data, BUT DOES NOT CLEAR IT FROM MEMORY YET
1529 hidnplayr 1276
;
1277
;  IN:  eax = ptr to ring struct
1278
;       ecx = buffer size
1279
;       edi = ptr to buffer
1280
;
1533 hidnplayr 1281
;  OUT: ecx = number of bytes read
1529 hidnplayr 1282
;
1283
;-----------------------------------------------------------------
1284
align 4
1285
SOCKET_ring_read:
1286
 
2402 hidnplayr 1287
        DEBUGF  1,"SOCKET_ring_read: ringbuff=%x ptr=%x size=%u\n", eax, edi, ecx
1529 hidnplayr 1288
 
2402 hidnplayr 1289
        cmp     ecx, [eax + RING_BUFFER.size]
1290
        ja      .less_data
1529 hidnplayr 1291
 
1292
  .copy:
2402 hidnplayr 1293
        mov     esi, [eax + RING_BUFFER.read_ptr]
1529 hidnplayr 1294
 
2402 hidnplayr 1295
        DEBUGF  2,"SOCKET_ring_read: %u bytes from %x to %x\n", ecx, esi, edi
1296
        push    ecx
1297
        shr     ecx, 1
1298
        jnc     .nb
1299
        movsb
1536 hidnplayr 1300
  .nb:
2402 hidnplayr 1301
        shr     ecx, 1
1302
        jnc     .nw
1303
        movsw
1536 hidnplayr 1304
  .nw:
2402 hidnplayr 1305
        test    ecx, ecx
1306
        jz      .nd
1307
        rep     movsd
1536 hidnplayr 1308
  .nd:
2402 hidnplayr 1309
        pop     ecx
1529 hidnplayr 1310
 
1830 hidnplayr 1311
  .no_data_at_all:
2402 hidnplayr 1312
        ret
1529 hidnplayr 1313
 
1533 hidnplayr 1314
  .less_data:
2402 hidnplayr 1315
        mov     ecx, [eax + RING_BUFFER.size]
2888 hidnplayr 1316
        cmp     ecx, 0
1317
        jb      .error
2402 hidnplayr 1318
        jmp     .copy
1529 hidnplayr 1319
 
2888 hidnplayr 1320
  .error:
1321
        DEBUGF  1,"SOCKET_ring_read: ringbuff=%x error!", eax
1322
        xor     ecx, ecx
1323
        ret
1529 hidnplayr 1324
 
1325
;-----------------------------------------------------------------
1326
;
1327
; SOCKET_ring_free
1328
;
1329
; Free's some bytes from the ringbuffer
1330
;
1331
;  IN:  eax = ptr to ring struct
1332
;       ecx = data size
1333
;
1334
;  OUT: ecx = number of bytes free-ed
1335
;
1336
;-----------------------------------------------------------------
1337
align 4
1338
SOCKET_ring_free:
1339
 
2402 hidnplayr 1340
        DEBUGF  1,"SOCKET_ring_free: %u bytes from ring %x\n", ecx, eax
1529 hidnplayr 1341
 
2402 hidnplayr 1342
        sub     [eax + RING_BUFFER.size], ecx
2888 hidnplayr 1343
        jb      .error
2402 hidnplayr 1344
        add     [eax + RING_BUFFER.read_ptr], ecx
1529 hidnplayr 1345
 
2402 hidnplayr 1346
        mov     edx, [eax + RING_BUFFER.end_ptr]
1347
        cmp     [eax + RING_BUFFER.read_ptr], edx
1348
        jb      @f
1349
        sub     [eax + RING_BUFFER.read_ptr], SOCKET_MAXDATA
1529 hidnplayr 1350
       @@:
2402 hidnplayr 1351
        ret
1529 hidnplayr 1352
 
2888 hidnplayr 1353
  .error:       ; we could free all available bytes, but that would be stupid, i guess..
1354
        DEBUGF  1,"SOCKET_ring_free: buffer=%x error!\n", eax
2402 hidnplayr 1355
        add     [eax + RING_BUFFER.size], ecx
1356
        xor     ecx, ecx
1357
        ret
1529 hidnplayr 1358
 
1359
 
1360
;-----------------------------------------------------------------
1361
;
1514 hidnplayr 1362
; SOCKET_notify_owner
1363
;
1364
; notify's the owner of a socket that something happened
1365
;
1366
;  IN:  eax = socket ptr
1367
;  OUT: /
1368
;
1369
;-----------------------------------------------------------------
1370
align 4
1371
SOCKET_notify_owner:
1372
 
2402 hidnplayr 1373
        DEBUGF  1,"SOCKET_notify_owner: %x\n", eax
1514 hidnplayr 1374
 
2402 hidnplayr 1375
        call    SOCKET_check
1376
        jz      .error
1514 hidnplayr 1377
 
2402 hidnplayr 1378
        push    eax ecx esi
1514 hidnplayr 1379
 
1380
; socket exists, now try to flag an event to the application
1381
 
2402 hidnplayr 1382
        mov     eax, [eax + SOCKET.PID]
2629 hidnplayr 1383
        test    eax, eax
1384
        jz      .error2
2402 hidnplayr 1385
        mov     ecx, 1
1386
        mov     esi, TASK_DATA + TASKDATA.pid
1206 hidnplayr 1387
 
1388
       .next_pid:
2402 hidnplayr 1389
        cmp     [esi], eax
1390
        je      .found_pid
1391
        inc     ecx
1392
        add     esi, 0x20
1393
        cmp     ecx, [TASK_COUNT]
1394
        jbe     .next_pid
1206 hidnplayr 1395
 
1514 hidnplayr 1396
; PID not found, TODO: close socket!
1397
 
2402 hidnplayr 1398
        jmp     .error2
1514 hidnplayr 1399
 
1206 hidnplayr 1400
       .found_pid:
2402 hidnplayr 1401
        shl     ecx, 8
1402
        or      [ecx + SLOT_BASE + APPDATA.event_mask], EVENT_NETWORK
1403
        mov     [check_idle_semaphore], 200
1206 hidnplayr 1404
 
2402 hidnplayr 1405
        DEBUGF  1,"SOCKET_notify_owner: succes!\n"
1514 hidnplayr 1406
 
1407
  .error2:
2402 hidnplayr 1408
        pop     esi ecx eax
1536 hidnplayr 1409
 
1514 hidnplayr 1410
  .error:
1411
 
2402 hidnplayr 1412
        ret
1206 hidnplayr 1413
 
1414
 
1514 hidnplayr 1415
;--------------------------------------------------------------------
1416
;
1417
; SOCKET_alloc
1418
;
1159 hidnplayr 1419
; Allocate memory for socket data and put new socket into the list
1420
; Newly created socket is initialized with calling PID and number and
1421
; put into beginning of list (which is a fastest way).
1422
;
1514 hidnplayr 1423
; IN:  /
1424
; OUT: eax = 0 on error, socket ptr otherwise
1425
;      edi = socket number
1426
;       ZF = cleared on error
1159 hidnplayr 1427
;
1514 hidnplayr 1428
;--------------------------------------------------------------------
1429
align 4
1430
SOCKET_alloc:
1431
 
2402 hidnplayr 1432
        push    ebx
1514 hidnplayr 1433
 
2402 hidnplayr 1434
        stdcall kernel_alloc, SOCKETBUFFSIZE
1435
        DEBUGF  1, "SOCKET_alloc: ptr=%x\n", eax
1436
        or      eax, eax
1437
        jz      .exit
1159 hidnplayr 1438
 
1514 hidnplayr 1439
; zero-initialize allocated memory
2402 hidnplayr 1440
        push    eax
1441
        mov     edi, eax
1442
        mov     ecx, SOCKETBUFFSIZE / 4
1443
        xor     eax, eax
1444
        rep     stosd
1445
        pop     eax
1159 hidnplayr 1446
 
1536 hidnplayr 1447
; set send-and receive procedures to return -1
2402 hidnplayr 1448
        mov     [eax + SOCKET.snd_proc], s_error
1449
        mov     [eax + SOCKET.rcv_proc], s_error
1536 hidnplayr 1450
 
1514 hidnplayr 1451
; find first free socket number and use it
2402 hidnplayr 1452
        mov     edi, [last_socket_num]
1159 hidnplayr 1453
  .next_socket_number:
2402 hidnplayr 1454
        inc     edi
1455
        jz      .next_socket_number     ; avoid socket nr 0
1456
        cmp     edi, -1
1457
        je      .next_socket_number     ; avoid socket nr -1
1458
        mov     ebx, net_sockets
1159 hidnplayr 1459
  .next_socket:
2402 hidnplayr 1460
        mov     ebx, [ebx + SOCKET.NextPtr]
1461
        test    ebx, ebx
1462
        jz      .last_socket
1536 hidnplayr 1463
 
2402 hidnplayr 1464
        cmp     [ebx + SOCKET.Number], edi
1465
        jne     .next_socket
1466
        jmp     .next_socket_number
1159 hidnplayr 1467
 
1514 hidnplayr 1468
  .last_socket:
2402 hidnplayr 1469
        mov     [last_socket_num], edi
1470
        mov     [eax + SOCKET.Number], edi
1471
        DEBUGF  1, "SOCKET_alloc: number=%u\n", edi
1159 hidnplayr 1472
 
1514 hidnplayr 1473
; Fill in PID
2402 hidnplayr 1474
        mov     ebx, [TASK_BASE]
1475
        mov     ebx, [ebx + TASKDATA.pid]
1476
        mov     [eax + SOCKET.PID], ebx
1514 hidnplayr 1477
 
2403 hidnplayr 1478
; init mutex
1479
        pusha
1480
        lea     ecx, [eax + SOCKET.mutex]
1481
        call    mutex_init
1482
        popa
1483
 
1529 hidnplayr 1484
; add socket to the list by re-arranging some pointers
2402 hidnplayr 1485
        mov     ebx, [net_sockets + SOCKET.NextPtr]
1514 hidnplayr 1486
 
2402 hidnplayr 1487
        mov     [eax + SOCKET.PrevPtr], net_sockets
1488
        mov     [eax + SOCKET.NextPtr], ebx
1514 hidnplayr 1489
 
2402 hidnplayr 1490
        test    ebx, ebx
1491
        jz      @f
1492
 
1493
        pusha
1494
        lea     ecx, [ebx + SOCKET.mutex]
1495
        call    mutex_lock
1496
        popa
1497
 
1498
        mov     [ebx + SOCKET.PrevPtr], eax
1499
 
1500
        pusha
1501
        lea     ecx, [ebx + SOCKET.mutex]
1502
        call    mutex_unlock
1503
        popa
1514 hidnplayr 1504
       @@:
1505
 
2402 hidnplayr 1506
        mov     [net_sockets + SOCKET.NextPtr], eax
1507
        or      eax, eax                ; used to clear zero flag
1159 hidnplayr 1508
  .exit:
2402 hidnplayr 1509
        pop     ebx
1514 hidnplayr 1510
 
2402 hidnplayr 1511
        ret
1159 hidnplayr 1512
 
1514 hidnplayr 1513
 
1514
;----------------------------------------------------
1159 hidnplayr 1515
;
1514 hidnplayr 1516
; SOCKET_free
1159 hidnplayr 1517
;
1514 hidnplayr 1518
; Free socket data memory and remove socket from the list
1519
;
1520
; IN:  eax = socket ptr
1521
; OUT: /
1522
;
1523
;----------------------------------------------------
1524
align 4
1525
SOCKET_free:
1159 hidnplayr 1526
 
2402 hidnplayr 1527
        DEBUGF  1, "SOCKET_free: %x\n", eax
1514 hidnplayr 1528
 
2402 hidnplayr 1529
        call    SOCKET_check
1530
        jz      .error
1159 hidnplayr 1531
 
2402 hidnplayr 1532
        push    ebx
1514 hidnplayr 1533
 
2402 hidnplayr 1534
        pusha
1535
        lea     ecx, [eax + SOCKET.mutex]
1536
        call    mutex_lock
1537
        popa
1514 hidnplayr 1538
 
2402 hidnplayr 1539
        cmp     [eax + SOCKET.Domain], AF_INET4
1540
        jnz     .no_tcp
1529 hidnplayr 1541
 
2402 hidnplayr 1542
        cmp     [eax + SOCKET.Protocol], IP_PROTO_TCP
1543
        jnz     .no_tcp
1544
 
1545
        mov     ebx, eax
1546
        stdcall kernel_free, [ebx + STREAM_SOCKET.rcv.start_ptr]
1547
        stdcall kernel_free, [ebx + STREAM_SOCKET.snd.start_ptr]
1548
        mov     eax, ebx
1536 hidnplayr 1549
  .no_tcp:
1529 hidnplayr 1550
 
2402 hidnplayr 1551
        push    eax                             ; this will be passed to kernel_free
1552
        mov     ebx, [eax + SOCKET.NextPtr]
1553
        mov     eax, [eax + SOCKET.PrevPtr]
1514 hidnplayr 1554
 
2402 hidnplayr 1555
        DEBUGF  1, "SOCKET_free: linking socket %x to socket %x\n", eax, ebx
1514 hidnplayr 1556
 
2402 hidnplayr 1557
        test    eax, eax
1558
        jz      @f
1559
        mov     [eax + SOCKET.NextPtr], ebx
1514 hidnplayr 1560
       @@:
1159 hidnplayr 1561
 
2402 hidnplayr 1562
        test    ebx, ebx
1563
        jz      @f
1564
        mov     [ebx + SOCKET.PrevPtr], eax
1514 hidnplayr 1565
       @@:
1249 hidnplayr 1566
 
2402 hidnplayr 1567
        call    kernel_free
1568
        pop     ebx
1159 hidnplayr 1569
 
2402 hidnplayr 1570
        DEBUGF  1, "SOCKET_free: success!\n"
1514 hidnplayr 1571
 
1159 hidnplayr 1572
  .error:
2402 hidnplayr 1573
        ret
1159 hidnplayr 1574
 
1543 hidnplayr 1575
;------------------------------------
1576
;
1577
; SOCKET_fork
1578
;
1579
; Create a child socket
1580
;
1533 hidnplayr 1581
; IN:  socket nr in ebx
1543 hidnplayr 1582
; OUT: child socket nr in eax
1583
;
1584
;-----------------------------------
1529 hidnplayr 1585
align 4
1586
SOCKET_fork:
1587
 
2402 hidnplayr 1588
        DEBUGF  1,"SOCKET_fork: %x\n", ebx
1529 hidnplayr 1589
 
1543 hidnplayr 1590
; Exit if backlog queue is full
2402 hidnplayr 1591
        mov     eax, [ebx + SOCKET_QUEUE_LOCATION + queue.size]
1592
        cmp     ax, [ebx + SOCKET.backlog]
1593
        jae     .fail
1543 hidnplayr 1594
 
1529 hidnplayr 1595
; Allocate new socket
2402 hidnplayr 1596
        push    ebx
1597
        call    SOCKET_alloc
1598
        pop     ebx
1599
        jz      .fail
1529 hidnplayr 1600
 
2402 hidnplayr 1601
        push    eax
1602
        mov     esi, esp
1603
        add_to_queue (ebx + SOCKET_QUEUE_LOCATION), MAX_backlog, 4, .fail2
1604
        pop     eax
1543 hidnplayr 1605
 
1606
; Copy structure from current socket to new
1607
; We start at PID to preserve the socket num, and the 2 pointers at beginning of socket
2402 hidnplayr 1608
        lea     esi, [ebx + SOCKET.PID]
1609
        lea     edi, [eax + SOCKET.PID]
1610
        mov     ecx, (SOCKET_QUEUE_LOCATION - SOCKET.PID + 3)/4
1611
        rep     movsd
1529 hidnplayr 1612
 
2402 hidnplayr 1613
        and     [eax + SOCKET.options], not SO_ACCEPTCON
1529 hidnplayr 1614
 
2402 hidnplayr 1615
        ret
1529 hidnplayr 1616
 
1543 hidnplayr 1617
  .fail2:
2402 hidnplayr 1618
        add     esp, 4+4+4
1543 hidnplayr 1619
  .fail:
2402 hidnplayr 1620
        DEBUGF  1,"SOCKET_fork: failed\n"
1621
        xor     eax, eax
1622
        ret
1529 hidnplayr 1623
 
1543 hidnplayr 1624
 
1514 hidnplayr 1625
;---------------------------------------------------
1626
;
1627
; SOCKET_num_to_ptr
1628
;
1159 hidnplayr 1629
; Get socket structure address by its number
1630
;
1514 hidnplayr 1631
; IN:  ecx = socket number
1533 hidnplayr 1632
; OUT: eax = 0 on error, socket ptr otherwise
1514 hidnplayr 1633
;       ZF = set on error
1159 hidnplayr 1634
;
1514 hidnplayr 1635
;---------------------------------------------------
1636
align 4
1637
SOCKET_num_to_ptr:
1159 hidnplayr 1638
 
2402 hidnplayr 1639
        DEBUGF  1,"SOCKET_num_to_ptr: %u ", ecx
1514 hidnplayr 1640
 
2402 hidnplayr 1641
        mov     eax, net_sockets
1514 hidnplayr 1642
 
1159 hidnplayr 1643
  .next_socket:
2402 hidnplayr 1644
        mov     eax, [eax + SOCKET.NextPtr]
1645
        or      eax, eax
1646
        jz      .error
1647
        cmp     [eax + SOCKET.Number], ecx
1648
        jne     .next_socket
1159 hidnplayr 1649
 
2402 hidnplayr 1650
        test    eax, eax
1159 hidnplayr 1651
 
2402 hidnplayr 1652
        DEBUGF  1,"(%x)\n", eax
1159 hidnplayr 1653
  .error:
2402 hidnplayr 1654
        ret
1159 hidnplayr 1655
 
1514 hidnplayr 1656
 
1657
;---------------------------------------------------
1159 hidnplayr 1658
;
1514 hidnplayr 1659
; SOCKET_ptr_to_num
1159 hidnplayr 1660
;
1514 hidnplayr 1661
; Get socket number by its address
1662
;
1663
; IN:  eax = socket ptr
1664
; OUT: eax = 0 on error, socket num otherwise
1665
;       ZF = set on error
1666
;
1667
;---------------------------------------------------
1668
align 4
1669
SOCKET_ptr_to_num:
1670
 
2402 hidnplayr 1671
        DEBUGF  1,"SOCKET_ptr_to_num: %x ", eax
1514 hidnplayr 1672
 
2402 hidnplayr 1673
        call    SOCKET_check
1674
        jz      .error
1159 hidnplayr 1675
 
2402 hidnplayr 1676
        mov     eax, [eax + SOCKET.Number]
1514 hidnplayr 1677
 
2402 hidnplayr 1678
        DEBUGF  1,"(%u)\n", eax
1514 hidnplayr 1679
 
1680
  .error:
2402 hidnplayr 1681
        ret
1514 hidnplayr 1682
 
1683
 
1684
;---------------------------------------------------
1685
;
1686
; SOCKET_check
1687
;
1688
; checks if the given value is really a socket ptr
1689
;
1690
; IN:  eax = socket ptr
1691
; OUT: eax = 0 on error, unchanged otherwise
1692
;       ZF = set on error
1693
;
1694
;---------------------------------------------------
1695
align 4
1696
SOCKET_check:
1697
 
2402 hidnplayr 1698
        DEBUGF  1,"SOCKET_check: %x\n", eax
1514 hidnplayr 1699
 
2402 hidnplayr 1700
        push    ebx
1701
        mov     ebx, net_sockets
1514 hidnplayr 1702
 
1159 hidnplayr 1703
  .next_socket:
2402 hidnplayr 1704
        mov     ebx, [ebx + SOCKET.NextPtr]
1705
        or      ebx, ebx
1706
        jz      .done
1707
        cmp     ebx, eax
1708
        jnz     .next_socket
1159 hidnplayr 1709
 
1514 hidnplayr 1710
  .done:
2402 hidnplayr 1711
        mov     eax, ebx
1712
        test    eax, eax
1713
        pop     ebx
1514 hidnplayr 1714
 
2402 hidnplayr 1715
        ret
1159 hidnplayr 1716
 
1514 hidnplayr 1717
 
1718
 
1719
;---------------------------------------------------
1720
;
1721
; SOCKET_check_owner
1722
;
1723
; checks if the caller application owns the socket
1724
;
1725
; IN:  eax = socket ptr
1726
; OUT:  ZF = true/false
1727
;
1728
;---------------------------------------------------
1729
align 4
1730
SOCKET_check_owner:
1731
 
2402 hidnplayr 1732
        DEBUGF  1,"SOCKET_check_owner: %x\n", eax
1514 hidnplayr 1733
 
2402 hidnplayr 1734
        push    ebx
1735
        mov     ebx, [TASK_BASE]
1736
        mov     ebx, [ecx + TASKDATA.pid]
1737
        cmp     [eax + SOCKET.PID], ebx
1738
        pop      ebx
1514 hidnplayr 1739
 
2402 hidnplayr 1740
        ret
1514 hidnplayr 1741
 
1742
 
1743
 
1744
 
1885 hidnplayr 1745
;------------------------------------------------------
1514 hidnplayr 1746
;
1747
; SOCKET_process_end
1748
;
1749
; Kernel calls this function when a certain process ends
1750
; This function will check if the process had any open sockets
1751
; And update them accordingly
1752
;
2867 hidnplayr 1753
; IN:  edx = pid
1514 hidnplayr 1754
; OUT: /
1755
;
1756
;------------------------------------------------------
1757
align 4
1758
SOCKET_process_end:
1759
 
2867 hidnplayr 1760
        DEBUGF  1,"SOCKET_process_end: %x\n", edx
1514 hidnplayr 1761
 
2402 hidnplayr 1762
        push    ebx
1763
        mov     ebx, net_sockets
1514 hidnplayr 1764
 
1765
  .next_socket:
2402 hidnplayr 1766
        mov     ebx, [ebx + SOCKET.NextPtr]
1514 hidnplayr 1767
  .test_socket:
2402 hidnplayr 1768
        test    ebx, ebx
1769
        jz      .done
1514 hidnplayr 1770
 
2867 hidnplayr 1771
        cmp     [ebx + SOCKET.PID], edx
2402 hidnplayr 1772
        jne     .next_socket
1514 hidnplayr 1773
 
2868 hidnplayr 1774
        DEBUGF  1,"killing socket %x\n", ebx
1514 hidnplayr 1775
 
2402 hidnplayr 1776
        mov     [ebx + SOCKET.PID], 0
1514 hidnplayr 1777
 
2402 hidnplayr 1778
        cmp     [ebx + SOCKET.Protocol], IP_PROTO_TCP
1779
        je      .tcp
1514 hidnplayr 1780
 
2629 hidnplayr 1781
; The socket is stateless, just kill it right away!
1514 hidnplayr 1782
 
2402 hidnplayr 1783
        mov     eax, ebx
1784
        mov     ebx, [ebx + SOCKET.NextPtr]
1785
        call    SOCKET_free
1786
        jmp     .test_socket
1514 hidnplayr 1787
 
1788
  .tcp:
2629 hidnplayr 1789
        push    [ebx + SOCKET.NextPtr]
1790
        mov     eax, ebx
2869 hidnplayr 1791
        call    TCP_disconnect
2629 hidnplayr 1792
        pop     ebx
1793
        jmp     .test_socket
1885 hidnplayr 1794
 
1514 hidnplayr 1795
  .done:
2402 hidnplayr 1796
        pop     ebx
1514 hidnplayr 1797
 
2402 hidnplayr 1798
        ret
1773 hidnplayr 1799
 
1800
 
1801
 
1802
 
1885 hidnplayr 1803
;-----------------------------------------------------------------
1804
;
1805
; SOCKET_is_connecting
1806
;
1807
;  IN:  eax = socket ptr
1808
;  OUT: /
1809
;
1810
;-----------------------------------------------------------------
1773 hidnplayr 1811
 
1885 hidnplayr 1812
align 4
1813
SOCKET_is_connecting:
1773 hidnplayr 1814
 
1815
 
2402 hidnplayr 1816
        and     [eax + SOCKET.options], not (SS_ISCONNECTED + SS_ISDISCONNECTING + SS_ISCONFIRMING)
1817
        or      [eax + SOCKET.options], SS_ISCONNECTING
1773 hidnplayr 1818
 
2402 hidnplayr 1819
        jmp     SOCKET_notify_owner
1885 hidnplayr 1820
 
1821
 
1822
 
1773 hidnplayr 1823
;-----------------------------------------------------------------
1824
;
1885 hidnplayr 1825
; SOCKET_is_connected
1826
;
1827
;  IN:  eax = socket ptr
1828
;  OUT: /
1829
;
1830
;-----------------------------------------------------------------
1831
 
1832
align 4
1833
SOCKET_is_connected:
1834
 
1835
 
2402 hidnplayr 1836
        and     [eax + SOCKET.options], not (SS_ISCONNECTING + SS_ISDISCONNECTING + SS_ISCONFIRMING)
1837
        or      [eax + SOCKET.options], SS_ISCONNECTED
1885 hidnplayr 1838
 
2402 hidnplayr 1839
        jmp     SOCKET_notify_owner
1885 hidnplayr 1840
 
1841
 
1842
 
1843
 
1844
;-----------------------------------------------------------------
1845
;
1773 hidnplayr 1846
; SOCKET_is_disconnecting
1847
;
1848
;  IN:  eax = socket ptr
1849
;  OUT: /
1850
;
1851
;-----------------------------------------------------------------
1852
 
1853
align 4
1854
SOCKET_is_disconnecting:
1855
 
2402 hidnplayr 1856
        and     [eax + SOCKET.options], not (SS_ISCONNECTING)
1857
        or      [eax + SOCKET.options], SS_ISDISCONNECTING + SS_CANTRCVMORE + SS_CANTSENDMORE
1773 hidnplayr 1858
 
2402 hidnplayr 1859
        jmp     SOCKET_notify_owner
1773 hidnplayr 1860
 
1861
 
1862
 
1863
;-----------------------------------------------------------------
1864
;
1865
; SOCKET_is_disconnected
1866
;
1867
;  IN:  eax = socket ptr
1868
;  OUT: /
1869
;
1870
;-----------------------------------------------------------------
1871
 
1872
align 4
1873
SOCKET_is_disconnected:
1874
 
2402 hidnplayr 1875
        and     [eax + SOCKET.options], not (SS_ISCONNECTING + SS_ISCONNECTED + SS_ISDISCONNECTING)
1876
        or      [eax + SOCKET.options], SS_CANTRCVMORE + SS_CANTSENDMORE
1773 hidnplayr 1877
 
2402 hidnplayr 1878
        jmp     SOCKET_notify_owner
1774 hidnplayr 1879
 
1880
 
1881
;-----------------------------------------------------------------
1882
;
1883
; SOCKET_cant_recv_more
1884
;
1885
;  IN:  eax = socket ptr
1886
;  OUT: /
1887
;
1888
;-----------------------------------------------------------------
1889
 
1890
align 4
1891
SOCKET_cant_recv_more:
1892
 
2402 hidnplayr 1893
        or      [eax + SOCKET.options], SS_CANTRCVMORE
1885 hidnplayr 1894
 
2402 hidnplayr 1895
        ret
1831 hidnplayr 1896
 
1897
 
1898
 
1899
;-----------------------------------------------------------------
1900
;
1885 hidnplayr 1901
; SOCKET_cant_send_more
1831 hidnplayr 1902
;
1903
;  IN:  eax = socket ptr
1904
;  OUT: /
1905
;
1906
;-----------------------------------------------------------------
1907
 
1908
align 4
1885 hidnplayr 1909
SOCKET_cant_send_more:
1831 hidnplayr 1910
 
2402 hidnplayr 1911
        or      [eax + SOCKET.options], SS_CANTSENDMORE
1831 hidnplayr 1912
 
2402 hidnplayr 1913
        ret