Subversion Repositories Kolibri OS

Rev

Rev 3406 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

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