Subversion Repositories Kolibri OS

Rev

Rev 3459 | 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: 3461 $
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
3461 hidnplayr 879
        jnz     .return0
1159 hidnplayr 880
 
3257 hidnplayr 881
        call    SOCKET_block
882
        jmp     .loop
2994 hidnplayr 883
 
3461 hidnplayr 884
  .return0:
885
        xor     ecx, ecx
886
        mov     [esp+32], ecx
887
        ret
3257 hidnplayr 888
 
3461 hidnplayr 889
 
1257 hidnplayr 890
;-----------------------------------------------------------------
1159 hidnplayr 891
;
892
; SOCKET_send
893
;
894
;
895
;  IN:  socket number in ecx
1206 hidnplayr 896
;       pointer to data in edx
897
;       datalength in esi
1159 hidnplayr 898
;       flags in edi
899
;  OUT: -1 on error
900
;
1257 hidnplayr 901
;-----------------------------------------------------------------
1206 hidnplayr 902
align 4
1514 hidnplayr 903
SOCKET_send:
1159 hidnplayr 904
 
3251 hidnplayr 905
        DEBUGF  2,"SOCKET_send: socknum=%u data ptr=%x length=%u flags=%x\n", ecx, edx, esi, edi
1159 hidnplayr 906
 
2402 hidnplayr 907
        call    SOCKET_num_to_ptr
908
        jz      s_error
1159 hidnplayr 909
 
2402 hidnplayr 910
        mov     ecx, esi
911
        mov     esi, edx
1763 hidnplayr 912
 
2402 hidnplayr 913
        jmp     [eax + SOCKET.snd_proc]
1206 hidnplayr 914
 
915
 
1536 hidnplayr 916
align 4
917
SOCKET_send_udp:
1529 hidnplayr 918
 
2402 hidnplayr 919
        DEBUGF  1,"SOCKET_send: UDP\n"
1159 hidnplayr 920
 
2573 hidnplayr 921
        mov     [esp+32], ecx
2402 hidnplayr 922
        call    UDP_output
2573 hidnplayr 923
        cmp     eax, -1
924
        je      s_error
2402 hidnplayr 925
        ret
1159 hidnplayr 926
 
927
 
1536 hidnplayr 928
align 4
929
SOCKET_send_tcp:
1254 hidnplayr 930
 
2402 hidnplayr 931
        DEBUGF  1,"SOCKET_send: TCP\n"
1254 hidnplayr 932
 
2402 hidnplayr 933
        push    eax
934
        add     eax, STREAM_SOCKET.snd
935
        call    SOCKET_ring_write
936
        pop     eax
1536 hidnplayr 937
 
2621 hidnplayr 938
        mov     [esp+32], ecx
939
 
2402 hidnplayr 940
        call    TCP_output
941
        ret
1159 hidnplayr 942
 
1249 hidnplayr 943
 
1543 hidnplayr 944
align 4
945
SOCKET_send_ip:
1249 hidnplayr 946
 
2891 hidnplayr 947
        DEBUGF  1,"SOCKET_send: IPv4\n"
1543 hidnplayr 948
 
2573 hidnplayr 949
        mov     [esp+32], ecx
2402 hidnplayr 950
        call    IPv4_output_raw
2573 hidnplayr 951
        cmp     eax, -1
952
        je      s_error
2402 hidnplayr 953
        ret
1543 hidnplayr 954
 
2573 hidnplayr 955
 
1541 hidnplayr 956
align 4
957
SOCKET_send_icmp:
1249 hidnplayr 958
 
2402 hidnplayr 959
        DEBUGF  1,"SOCKET_send: ICMP\n"
1541 hidnplayr 960
 
2573 hidnplayr 961
        mov     [esp+32], ecx
2402 hidnplayr 962
        call    ICMP_output_raw
2573 hidnplayr 963
        cmp     eax, -1
964
        je      s_error
2402 hidnplayr 965
        ret
1541 hidnplayr 966
 
967
 
2931 hidnplayr 968
align 4
969
SOCKET_send_pppoe:
1541 hidnplayr 970
 
2931 hidnplayr 971
        DEBUGF  1,"SOCKET_send: PPPoE\n"
1541 hidnplayr 972
 
2931 hidnplayr 973
        mov     [esp+32], ecx
974
        mov     ebx, [eax + SOCKET.device]
975
 
976
        call    PPPoE_discovery_output
977
        cmp     eax, -1
978
        je      s_error
979
        ret
980
 
981
 
982
 
3228 hidnplayr 983
align 4
3251 hidnplayr 984
SOCKET_send_local:
2931 hidnplayr 985
 
3229 hidnplayr 986
        ; does this socket have a PID yet?
987
        cmp     [eax + SOCKET.PID], 0
988
        jne     @f
989
 
990
        ; Change PID to that of current process
991
        mov     ebx, [TASK_BASE]
992
        mov     ebx, [ebx + TASKDATA.pid]
993
        mov     [eax + SOCKET.PID], ebx
3264 hidnplayr 994
        mov     [eax + SOCKET.TID], ebx         ; currently TID = PID in kolibrios :(
3229 hidnplayr 995
      @@:
3259 hidnplayr 996
        mov     [eax + SOCKET.snd_proc], SOCKET_send_local_
3229 hidnplayr 997
 
3259 hidnplayr 998
align 4
999
SOCKET_send_local_:
1000
 
1001
        DEBUGF  1,"SOCKET_send: LOCAL\n"
1002
 
3229 hidnplayr 1003
        ; get the other side's socket and check if it still exists
3228 hidnplayr 1004
        mov     eax, [eax + SOCKET.device]
1005
        call    SOCKET_check
1006
        jz      s_error
1007
 
3229 hidnplayr 1008
        ; allright, shove in the data!
3228 hidnplayr 1009
        push    eax
1010
        add     eax, STREAM_SOCKET.rcv
1011
        call    SOCKET_ring_write
1012
        pop     eax
1013
 
3229 hidnplayr 1014
        ; return the number of written bytes (or errorcode) to application
3228 hidnplayr 1015
        mov     [esp+32], ecx
1016
 
3229 hidnplayr 1017
        ; and notify the other end
3257 hidnplayr 1018
        call    SOCKET_notify
3228 hidnplayr 1019
 
1020
        ret
1021
 
1022
 
1257 hidnplayr 1023
;-----------------------------------------------------------------
1256 clevermous 1024
;
1257 hidnplayr 1025
; SOCKET_get_options
1256 clevermous 1026
;
1514 hidnplayr 1027
;  IN:  ecx = socket number
1028
;       edx = pointer to the options:
1257 hidnplayr 1029
;               dd      level, optname, optval, optlen
1256 clevermous 1030
;  OUT: -1 on error
1031
;
1032
; At moment, uses only pseudo-optname -2 for get last_ack_number for TCP.
1033
; TODO: find best way to notify that send()'ed data were acknowledged
1831 hidnplayr 1034
; Also pseudo-optname -3 is valid and returns socket state, one of TCPS_*.
1256 clevermous 1035
;
1257 hidnplayr 1036
;-----------------------------------------------------------------
1037
align 4
1514 hidnplayr 1038
SOCKET_get_opt:
1257 hidnplayr 1039
 
3251 hidnplayr 1040
        DEBUGF  2,"SOCKET_get_opt\n"
1514 hidnplayr 1041
 
2402 hidnplayr 1042
        call    SOCKET_num_to_ptr
1043
        jz      s_error
1514 hidnplayr 1044
 
2402 hidnplayr 1045
        cmp     dword [edx], IP_PROTO_TCP
1046
        jne     s_error
1047
        cmp     dword [edx+4], -2
1048
        je      @f
1049
        cmp     dword [edx+4], -3
1050
        jne     s_error
1299 clevermous 1051
@@:
1514 hidnplayr 1052
;        mov     eax, [edx+12]
1053
;        test    eax, eax
1054
;        jz      .fail
1055
;        cmp     dword [eax], 4
1056
;        mov     dword [eax], 4
1057
;        jb      .fail
1058
;        stdcall net_socket_num_to_addr, ecx
1059
;        test    eax, eax
1060
;        jz      .fail
1061
;        ; todo: check that eax is really TCP socket
1062
;        mov     ecx, [eax + TCP_SOCKET.last_ack_number]
1063
;        cmp     dword [edx+4], -2
1064
;        jz      @f
1065
;        mov     ecx, [eax + TCP_SOCKET.state]
1299 clevermous 1066
@@:
2402 hidnplayr 1067
        mov     eax, [edx+8]
1068
        test    eax, eax
1069
        jz      @f
1070
        mov     [eax], ecx
1256 clevermous 1071
@@:
2402 hidnplayr 1072
        mov     dword [esp+32], 0
1073
        ret
1159 hidnplayr 1074
 
1075
 
1529 hidnplayr 1076
 
2731 hidnplayr 1077
;-----------------------------------------------------------------
1078
;
1079
; SOCKET_set_options
1080
;
1081
;  IN:  ecx = socket number
1082
;       edx = pointer to the options:
2877 hidnplayr 1083
;               dd      level, optname, optlen, optval
2731 hidnplayr 1084
;  OUT: -1 on error
1085
;
1086
;-----------------------------------------------------------------
1542 hidnplayr 1087
align 4
1088
SOCKET_set_opt:
1089
 
3251 hidnplayr 1090
        DEBUGF  2,"SOCKET_set_opt\n"
2731 hidnplayr 1091
 
1092
        call    SOCKET_num_to_ptr
1093
        jz      s_error
1094
 
2877 hidnplayr 1095
        cmp     dword [edx], SOL_SOCKET
1096
        jne     s_error
2731 hidnplayr 1097
 
2877 hidnplayr 1098
        cmp     dword [edx+4], SO_BINDTODEVICE
1099
        je      .bind
2731 hidnplayr 1100
 
2996 hidnplayr 1101
        cmp     dword [edx+4], SO_BLOCK
1102
        je      .block
1103
 
2877 hidnplayr 1104
        jmp     s_error
1105
 
1106
  .bind:
1107
        cmp     dword [edx+8], 0
1108
        je      .unbind
1109
 
1110
        movzx   edx, byte [edx + 9]
1111
        cmp     edx, MAX_NET_DEVICES
1112
        ja      s_error
1113
 
1114
        mov     edx, [NET_DRV_LIST + 4*edx]
1115
        test    edx, edx
1116
        jz      s_error
1117
        mov     [eax + SOCKET.device], edx
1118
 
2891 hidnplayr 1119
        DEBUGF  1,"SOCKET_set_opt: Bound socket %x to device %x\n",eax, edx
2877 hidnplayr 1120
 
1121
        mov     dword [esp+32], 0       ; success!
2402 hidnplayr 1122
        ret
1542 hidnplayr 1123
 
2877 hidnplayr 1124
  .unbind:
1125
        mov     [eax + SOCKET.device], 0
1542 hidnplayr 1126
 
2877 hidnplayr 1127
        mov     dword [esp+32], 0       ; success!
1128
        ret
1542 hidnplayr 1129
 
2996 hidnplayr 1130
  .block:
1131
        cmp     dword [edx+8], 0
1132
        je      .unblock
2877 hidnplayr 1133
 
3257 hidnplayr 1134
        and     [eax + SOCKET.options], not SO_NONBLOCK
2877 hidnplayr 1135
 
2996 hidnplayr 1136
        mov     dword [esp+32], 0       ; success!
1137
        ret
1138
 
1139
  .unblock:
3257 hidnplayr 1140
        or      [eax + SOCKET.options], SO_NONBLOCK
2996 hidnplayr 1141
 
1142
        mov     dword [esp+32], 0       ; success!
1143
        ret
1144
 
1145
 
1146
 
3228 hidnplayr 1147
;-----------------------------------------------------------------
1148
;
1149
; SOCKET_pair
1150
;
3251 hidnplayr 1151
; Allocates a pair of linked LOCAL domain sockets
3228 hidnplayr 1152
;
1153
; IN: /
1154
; OUT: eax is socket1 num, -1 on error
1155
;      ebx is socket2 num
1156
;
1157
;-----------------------------------------------------------------
1158
align 4
1159
SOCKET_pair:
2996 hidnplayr 1160
 
3251 hidnplayr 1161
        DEBUGF  2,"SOCKET_pair\n"
2996 hidnplayr 1162
 
3228 hidnplayr 1163
        call    SOCKET_alloc
1164
        jz      s_error
1165
        mov     [esp+32], edi   ; application's eax
1166
 
3251 hidnplayr 1167
        mov     [eax + SOCKET.Domain], AF_LOCAL
3228 hidnplayr 1168
        mov     [eax + SOCKET.Type], SOCK_STREAM
1169
        mov     [eax + SOCKET.Protocol], 0              ;;; CHECKME
3251 hidnplayr 1170
        mov     [eax + SOCKET.snd_proc], SOCKET_send_local
3259 hidnplayr 1171
        mov     [eax + SOCKET.rcv_proc], SOCKET_receive_local
3261 hidnplayr 1172
        mov     [eax + SOCKET.PID], 0
3228 hidnplayr 1173
        mov     ebx, eax
1174
 
1175
        call    SOCKET_alloc
1176
        jz      .error
1177
        mov     [esp+24], edi   ; application's ebx
1178
 
3251 hidnplayr 1179
        mov     [eax + SOCKET.Domain], AF_LOCAL
3228 hidnplayr 1180
        mov     [eax + SOCKET.Type], SOCK_STREAM
1181
        mov     [eax + SOCKET.Protocol], 0              ;;; CHECKME
3251 hidnplayr 1182
        mov     [eax + SOCKET.snd_proc], SOCKET_send_local
3259 hidnplayr 1183
        mov     [eax + SOCKET.rcv_proc], SOCKET_receive_local
3261 hidnplayr 1184
        mov     [eax + SOCKET.PID], 0
3228 hidnplayr 1185
 
1186
        ; Link the two sockets to eachother
1187
        mov     [eax + SOCKET.device], ebx
1188
        mov     [ebx + SOCKET.device], eax
1189
 
1190
        lea     eax, [eax + STREAM_SOCKET.rcv]
1191
        call    SOCKET_ring_create
1192
 
1193
        lea     eax, [ebx + STREAM_SOCKET.rcv]
1194
        call    SOCKET_ring_create
1195
        pop     eax
1196
 
1197
        ret
1198
 
1199
  .error:
1200
        mov     eax, ebx
1201
        call    SOCKET_free
1202
        jmp     s_error
1203
 
1204
 
1205
 
1257 hidnplayr 1206
;-----------------------------------------------------------------
1206 hidnplayr 1207
;
1529 hidnplayr 1208
; SOCKET_debug
1209
;
1210
;  Copies socket variables to application buffer
1211
;
1212
;  IN:  ecx = socket number
1213
;       edx = pointer to buffer
1214
;
1215
;  OUT: -1 on error
1216
;-----------------------------------------------------------------
1217
align 4
1218
SOCKET_debug:
1219
 
3251 hidnplayr 1220
        DEBUGF  1,"SOCKET_debug\n"
1529 hidnplayr 1221
 
3146 hidnplayr 1222
        mov     edi, edx
1223
 
1224
        test    ecx, ecx
1225
        jz      .returnall
1226
 
2402 hidnplayr 1227
        call    SOCKET_num_to_ptr
1228
        jz      s_error
1529 hidnplayr 1229
 
2402 hidnplayr 1230
        mov     esi, eax
1231
        mov     ecx, SOCKETBUFFSIZE/4
1232
        rep     movsd
1529 hidnplayr 1233
 
2402 hidnplayr 1234
        mov     dword [esp+32], 0
1235
        ret
1529 hidnplayr 1236
 
3146 hidnplayr 1237
  .returnall:
1238
        mov     ebx, net_sockets
1239
  .next_socket:
1240
        mov     ebx, [ebx + SOCKET.NextPtr]
1241
        test    ebx, ebx
1242
        jz      .done
1243
        mov     eax, [ebx + SOCKET.Number]
1244
        stosd
1245
        jmp     .next_socket
1246
  .done:
1247
        xor     eax, eax
1248
        stosd
1529 hidnplayr 1249
 
3146 hidnplayr 1250
        mov     dword [esp+32], 0
1251
        ret
1252
 
1253
 
1529 hidnplayr 1254
;-----------------------------------------------------------------
1255
;
1514 hidnplayr 1256
; SOCKET_find_port
1206 hidnplayr 1257
;
1514 hidnplayr 1258
; Fills in the local port number for TCP and UDP sockets
1259
; This procedure always works because the number of sockets is
1260
; limited to a smaller number then the number of possible ports
1206 hidnplayr 1261
;
1514 hidnplayr 1262
;  IN:  eax = socket pointer
1263
;  OUT: /
1206 hidnplayr 1264
;
1257 hidnplayr 1265
;-----------------------------------------------------------------
1206 hidnplayr 1266
align 4
1514 hidnplayr 1267
SOCKET_find_port:
1159 hidnplayr 1268
 
3251 hidnplayr 1269
        DEBUGF  2,"SOCKET_find_port\n"
1159 hidnplayr 1270
 
2402 hidnplayr 1271
        push    ebx esi ecx
1514 hidnplayr 1272
 
2402 hidnplayr 1273
        cmp     [eax + SOCKET.Protocol], IP_PROTO_UDP
1274
        je      .udp
1159 hidnplayr 1275
 
2402 hidnplayr 1276
        cmp     [eax + SOCKET.Protocol], IP_PROTO_TCP
1277
        je      .tcp
1159 hidnplayr 1278
 
2402 hidnplayr 1279
        pop     ecx esi ebx
1280
        ret
1514 hidnplayr 1281
 
1206 hidnplayr 1282
  .udp:
2402 hidnplayr 1283
        mov     bx, [last_UDP_port]
1284
        call    .findit
1285
        mov     [last_UDP_port], bx
1206 hidnplayr 1286
 
2995 hidnplayr 1287
        pop     ecx esi ebx
1288
        ret
1289
 
1206 hidnplayr 1290
  .tcp:
2402 hidnplayr 1291
        mov     bx, [last_TCP_port]
1292
        call    .findit
1293
        mov     [last_TCP_port], bx
1206 hidnplayr 1294
 
2995 hidnplayr 1295
        pop     ecx esi ebx
1296
        ret
1206 hidnplayr 1297
 
2995 hidnplayr 1298
 
1514 hidnplayr 1299
  .restart:
2995 hidnplayr 1300
        mov     bx, MIN_EPHEMERAL_PORT_N
1514 hidnplayr 1301
  .findit:
2995 hidnplayr 1302
        cmp     bx, MAX_EPHEMERAL_PORT_N
1303
        je      .restart
1206 hidnplayr 1304
 
2995 hidnplayr 1305
        add     bh, 1
1306
        adc     bl, 0
1206 hidnplayr 1307
 
2402 hidnplayr 1308
        call    SOCKET_check_port
1309
        jz      .findit
1310
        ret
1206 hidnplayr 1311
 
1257 hidnplayr 1312
 
1313
 
1314
;-----------------------------------------------------------------
1206 hidnplayr 1315
;
1542 hidnplayr 1316
; SOCKET_check_port (to be used with AF_INET only!)
1206 hidnplayr 1317
;
1514 hidnplayr 1318
; Checks if a local port number is unused
1319
; If the proposed port number is unused, it is filled in in the socket structure
1206 hidnplayr 1320
;
1514 hidnplayr 1321
;  IN:  eax = socket ptr (to find out if its a TCP/UDP socket)
2995 hidnplayr 1322
;        bx = proposed socket number (network byte order)
1206 hidnplayr 1323
;
2995 hidnplayr 1324
;  OUT:  ZF = set on error
1514 hidnplayr 1325
;
1257 hidnplayr 1326
;-----------------------------------------------------------------
1206 hidnplayr 1327
align 4
1514 hidnplayr 1328
SOCKET_check_port:
1329
 
3251 hidnplayr 1330
        DEBUGF  2,"SOCKET_check_port: "
1514 hidnplayr 1331
 
2402 hidnplayr 1332
        mov     ecx, [eax + SOCKET.Protocol]
2622 hidnplayr 1333
        mov     edx, [eax + IP_SOCKET.LocalIP]
2402 hidnplayr 1334
        mov     esi, net_sockets
1206 hidnplayr 1335
 
1336
  .next_socket:
2402 hidnplayr 1337
        mov     esi, [esi + SOCKET.NextPtr]
1338
        or      esi, esi
1339
        jz      .port_ok
1206 hidnplayr 1340
 
2402 hidnplayr 1341
        cmp     [esi + SOCKET.Protocol], ecx
1342
        jne     .next_socket
1206 hidnplayr 1343
 
2622 hidnplayr 1344
        cmp     [esi + IP_SOCKET.LocalIP], edx
1345
        jne     .next_socket
1346
 
2402 hidnplayr 1347
        cmp     [esi + UDP_SOCKET.LocalPort], bx
1348
        jne     .next_socket
1206 hidnplayr 1349
 
3251 hidnplayr 1350
        DEBUGF  2,"local port %x already in use\n", bx  ; FIXME: find a way to print big endian values with debugf
2402 hidnplayr 1351
        ret
1206 hidnplayr 1352
 
1353
  .port_ok:
3251 hidnplayr 1354
        DEBUGF  2,"local port %x is free\n", bx         ; FIXME: find a way to print big endian values with debugf
2402 hidnplayr 1355
        mov     [eax + UDP_SOCKET.LocalPort], bx
2995 hidnplayr 1356
        or      bx, bx                                  ; clear the zero-flag
2402 hidnplayr 1357
        ret
1206 hidnplayr 1358
 
1359
 
1257 hidnplayr 1360
 
1361
;-----------------------------------------------------------------
1206 hidnplayr 1362
;
1514 hidnplayr 1363
; SOCKET_input
1206 hidnplayr 1364
;
1536 hidnplayr 1365
; Updates a (stateless) socket with received data
1206 hidnplayr 1366
;
1514 hidnplayr 1367
; Note: the mutex should already be set !
1206 hidnplayr 1368
;
1249 hidnplayr 1369
;  IN:  eax = socket ptr
1514 hidnplayr 1370
;       ecx = data size
1371
;       esi = ptr to data
1372
;       [esp] = ptr to buf
1373
;       [esp + 4] = buf size
1249 hidnplayr 1374
;
1514 hidnplayr 1375
;  OUT: /
1206 hidnplayr 1376
;
1257 hidnplayr 1377
;-----------------------------------------------------------------
1206 hidnplayr 1378
align 4
1514 hidnplayr 1379
SOCKET_input:
1206 hidnplayr 1380
 
3251 hidnplayr 1381
        DEBUGF  2,"SOCKET_input: socket=%x, data=%x size=%u\n", eax, esi, ecx
1206 hidnplayr 1382
 
2402 hidnplayr 1383
        mov     [esp+4], ecx
1384
        push    esi
1385
        mov     esi, esp
1514 hidnplayr 1386
 
2402 hidnplayr 1387
        add_to_queue (eax + SOCKET_QUEUE_LOCATION), SOCKET_QUEUE_SIZE, sizeof.socket_queue_entry, SOCKET_input.full
1514 hidnplayr 1388
 
3251 hidnplayr 1389
        DEBUGF  1,"SOCKET_input: success\n"
2402 hidnplayr 1390
        add     esp, sizeof.socket_queue_entry
1206 hidnplayr 1391
 
2402 hidnplayr 1392
        pusha
1393
        lea     ecx, [eax + SOCKET.mutex]
1394
        call    mutex_unlock
1395
        popa
1396
 
3257 hidnplayr 1397
        jmp     SOCKET_notify
2402 hidnplayr 1398
 
1514 hidnplayr 1399
  .full:
2402 hidnplayr 1400
        DEBUGF  2,"SOCKET_input: socket %x is full!\n", eax
1206 hidnplayr 1401
 
2402 hidnplayr 1402
        pusha
1403
        lea     ecx, [eax + SOCKET.mutex]
1404
        call    mutex_unlock
1405
        popa
1514 hidnplayr 1406
 
2402 hidnplayr 1407
        call    kernel_free
1408
        add     esp, 8
1533 hidnplayr 1409
 
2402 hidnplayr 1410
        ret
1411
 
1412
 
1533 hidnplayr 1413
;--------------------------
1414
;
1415
; eax = ptr to ring struct (just a buffer of the right size)
1416
;
1417
align 4
1418
SOCKET_ring_create:
1419
 
2402 hidnplayr 1420
        push    esi
1421
        mov     esi, eax
1543 hidnplayr 1422
 
2402 hidnplayr 1423
        push    edx
1424
        stdcall create_ring_buffer, SOCKET_MAXDATA, PG_SW
1425
        pop     edx
1533 hidnplayr 1426
 
2402 hidnplayr 1427
        DEBUGF  1,"SOCKET_ring_created: %x\n", eax
3307 hidnplayr 1428
 
1429
        pusha
1430
        lea     ecx, [esi + RING_BUFFER.mutex]
1431
        call    mutex_init
1432
        popa
1433
 
2402 hidnplayr 1434
        mov     [esi + RING_BUFFER.start_ptr], eax
1435
        mov     [esi + RING_BUFFER.write_ptr], eax
1436
        mov     [esi + RING_BUFFER.read_ptr], eax
1437
        mov     [esi + RING_BUFFER.size], 0
2888 hidnplayr 1438
        add     eax, SOCKET_MAXDATA
2402 hidnplayr 1439
        mov     [esi + RING_BUFFER.end_ptr], eax
1440
        mov     eax, esi
1441
        pop     esi
1533 hidnplayr 1442
 
2402 hidnplayr 1443
        ret
1533 hidnplayr 1444
 
1514 hidnplayr 1445
;-----------------------------------------------------------------
1446
;
1533 hidnplayr 1447
; SOCKET_ring_write
1529 hidnplayr 1448
;
1533 hidnplayr 1449
; Adds data to a stream socket, and updates write pointer and size
1529 hidnplayr 1450
;
1451
;  IN:  eax = ptr to ring struct
1452
;       ecx = data size
1453
;       esi = ptr to data
1454
;
1533 hidnplayr 1455
;  OUT: ecx = number of bytes stored
1529 hidnplayr 1456
;
1457
;-----------------------------------------------------------------
1458
align 4
1533 hidnplayr 1459
SOCKET_ring_write:
1529 hidnplayr 1460
 
2402 hidnplayr 1461
        DEBUGF  1,"SOCKET_ring_write: ringbuff=%x ptr=%x size=%u\n", eax, esi, ecx
1529 hidnplayr 1462
 
3307 hidnplayr 1463
; lock mutex
1464
        pusha
1465
        lea     ecx, [eax + RING_BUFFER.mutex]
1466
        call    mutex_lock                                      ; TODO: check what registers this function actually destroys
1467
        popa
1529 hidnplayr 1468
 
3307 hidnplayr 1469
; calculate available size
1470
        mov     edi, SOCKET_MAXDATA
1471
        sub     edi, [eax + RING_BUFFER.size]                   ; available buffer size in edi
1472
        cmp     ecx, edi
1473
        jbe     .copy
1474
        mov     ecx, edi
1529 hidnplayr 1475
  .copy:
2402 hidnplayr 1476
        mov     edi, [eax + RING_BUFFER.write_ptr]
1477
        DEBUGF  2,"SOCKET_ring_write: %u bytes from %x to %x\n", ecx, esi, edi
1529 hidnplayr 1478
 
3307 hidnplayr 1479
; update write ptr
1480
        push    edi
1481
        add     edi, ecx
1482
        cmp     edi, [eax + RING_BUFFER.end_ptr]
1483
        jb      @f
1484
        sub     edi, SOCKET_MAXDATA                             ; WRAP
1485
  @@:
1486
        mov     [eax + RING_BUFFER.write_ptr], edi
1487
        pop     edi
1488
 
1489
; update size
1490
        add     [eax + RING_BUFFER.size], ecx
1491
 
1492
; copy the data
2402 hidnplayr 1493
        push    ecx
1494
        shr     ecx, 1
1495
        jnc     .nb
1496
        movsb
1536 hidnplayr 1497
  .nb:
2402 hidnplayr 1498
        shr     ecx, 1
1499
        jnc     .nw
1500
        movsw
1536 hidnplayr 1501
  .nw:
2402 hidnplayr 1502
        test    ecx, ecx
1503
        jz      .nd
1504
        rep     movsd
1536 hidnplayr 1505
  .nd:
2402 hidnplayr 1506
        pop     ecx
1529 hidnplayr 1507
 
3307 hidnplayr 1508
; unlock mutex
1509
        push    eax ecx
1510
        lea     ecx, [eax + RING_BUFFER.mutex]
1511
        call    mutex_unlock                                    ; TODO: check what registers this function actually destroys
1512
        pop     ecx eax
1533 hidnplayr 1513
 
2402 hidnplayr 1514
        ret
1529 hidnplayr 1515
 
1516
;-----------------------------------------------------------------
1517
;
1518
; SOCKET_ring_read
1519
;
2893 hidnplayr 1520
;  IN:  eax = ring struct ptr
1521
;       ecx = bytes to read
1522
;       edx = offset
2994 hidnplayr 1523
;       edi = ptr to buffer start
1529 hidnplayr 1524
;
2994 hidnplayr 1525
;  OUT: eax = unchanged
1526
;       ecx = number of bytes read (0 on error)
1527
;       edx = destroyed
1528
;       esi = destroyed
1529
;       edi = ptr to buffer end
1529 hidnplayr 1530
;
1531
;-----------------------------------------------------------------
1532
align 4
1533
SOCKET_ring_read:
1534
 
2893 hidnplayr 1535
        DEBUGF  1,"SOCKET_ring_read: ringbuff=%x ptr=%x size=%u offset=%x\n", eax, edi, ecx, edx
1529 hidnplayr 1536
 
3307 hidnplayr 1537
        pusha
1538
        lea     ecx, [eax + RING_BUFFER.mutex]
1539
        call    mutex_lock                                      ; TODO: check what registers this function actually destroys
1540
        popa
1541
 
2893 hidnplayr 1542
        mov     esi, [eax + RING_BUFFER.read_ptr]
1543
        add     esi, edx                                        ; esi = start_ptr + offset
1544
 
1545
        neg     edx
1546
        add     edx, [eax + RING_BUFFER.size]                   ; edx = snd.size - offset
1547
        jle     .no_data_at_all
1548
 
3307 hidnplayr 1549
        pusha
1550
        lea     ecx, [eax + RING_BUFFER.mutex]
1551
        call    mutex_unlock                                    ; TODO: check what registers this function actually destroys
1552
        popa
1553
 
2893 hidnplayr 1554
        cmp     ecx, edx
2402 hidnplayr 1555
        ja      .less_data
1529 hidnplayr 1556
 
1557
  .copy:
2402 hidnplayr 1558
        DEBUGF  2,"SOCKET_ring_read: %u bytes from %x to %x\n", ecx, esi, edi
1559
        push    ecx
1560
        shr     ecx, 1
1561
        jnc     .nb
1562
        movsb
1536 hidnplayr 1563
  .nb:
2402 hidnplayr 1564
        shr     ecx, 1
1565
        jnc     .nw
1566
        movsw
1536 hidnplayr 1567
  .nw:
2402 hidnplayr 1568
        test    ecx, ecx
1569
        jz      .nd
1570
        rep     movsd
1536 hidnplayr 1571
  .nd:
2402 hidnplayr 1572
        pop     ecx
2893 hidnplayr 1573
        ret
1529 hidnplayr 1574
 
1830 hidnplayr 1575
  .no_data_at_all:
3307 hidnplayr 1576
        pusha
1577
        lea     ecx, [eax + RING_BUFFER.mutex]
1578
        call    mutex_unlock                                    ; TODO: check what registers this function actually destroys
1579
        popa
1580
 
2894 hidnplayr 1581
        DEBUGF  1,"SOCKET_ring_read: no data at all!\n"
2993 hidnplayr 1582
        xor     ecx, ecx
2402 hidnplayr 1583
        ret
1529 hidnplayr 1584
 
1533 hidnplayr 1585
  .less_data:
2893 hidnplayr 1586
        mov     ecx, edx
2402 hidnplayr 1587
        jmp     .copy
1529 hidnplayr 1588
 
1589
 
1590
;-----------------------------------------------------------------
1591
;
1592
; SOCKET_ring_free
1593
;
1594
; Free's some bytes from the ringbuffer
1595
;
1596
;  IN:  eax = ptr to ring struct
1597
;       ecx = data size
1598
;
1599
;  OUT: ecx = number of bytes free-ed
1600
;
1601
;-----------------------------------------------------------------
1602
align 4
1603
SOCKET_ring_free:
1604
 
2402 hidnplayr 1605
        DEBUGF  1,"SOCKET_ring_free: %u bytes from ring %x\n", ecx, eax
1529 hidnplayr 1606
 
3307 hidnplayr 1607
        push    eax ecx
1608
        lea     ecx, [eax + RING_BUFFER.mutex]
1609
        call    mutex_lock                                      ; TODO: check what registers this function actually destroys
1610
        pop     ecx eax
1611
 
2402 hidnplayr 1612
        sub     [eax + RING_BUFFER.size], ecx
2888 hidnplayr 1613
        jb      .error
2402 hidnplayr 1614
        add     [eax + RING_BUFFER.read_ptr], ecx
1529 hidnplayr 1615
 
2402 hidnplayr 1616
        mov     edx, [eax + RING_BUFFER.end_ptr]
1617
        cmp     [eax + RING_BUFFER.read_ptr], edx
1618
        jb      @f
1619
        sub     [eax + RING_BUFFER.read_ptr], SOCKET_MAXDATA
1529 hidnplayr 1620
       @@:
3307 hidnplayr 1621
 
1622
        push    eax ecx
1623
        lea     ecx, [eax + RING_BUFFER.mutex]                  ; TODO: check what registers this function actually destroys
1624
        call    mutex_unlock
1625
        pop     ecx eax
1626
 
2402 hidnplayr 1627
        ret
1529 hidnplayr 1628
 
2888 hidnplayr 1629
  .error:       ; we could free all available bytes, but that would be stupid, i guess..
1630
        DEBUGF  1,"SOCKET_ring_free: buffer=%x error!\n", eax
2402 hidnplayr 1631
        add     [eax + RING_BUFFER.size], ecx
3307 hidnplayr 1632
 
1633
        push    eax
1634
        lea     ecx, [eax + RING_BUFFER.mutex]
1635
        call    mutex_unlock                                    ; TODO: check what registers this function actually destroys
1636
        pop     eax
1637
 
2402 hidnplayr 1638
        xor     ecx, ecx
1639
        ret
1529 hidnplayr 1640
 
1641
 
1642
;-----------------------------------------------------------------
1643
;
3257 hidnplayr 1644
; SOCKET_block
1514 hidnplayr 1645
;
3257 hidnplayr 1646
; Suspends the thread attached to a socket
1647
;
1648
;  IN:  eax = socket ptr
1649
;  OUT: /
1650
;
1651
;-----------------------------------------------------------------
1652
align 4
1653
SOCKET_block:
1654
 
1655
        DEBUGF  1,"SOCKET_block: %x\n", eax
1656
 
1657
        pushf
1658
        cli
1659
 
1660
        ; Set the 'socket is blocked' flag
1661
        or      [eax + SOCKET.state], SS_BLOCKED
1662
 
1663
        ; Suspend the thread
1664
        push    edx
1665
        mov     edx, [TASK_BASE]
1666
        mov     [edx + TASKDATA.state], 1               ; Suspended
3264 hidnplayr 1667
 
1668
        ; Remember the thread ID so we can wake it up again
1669
        mov     edx, [edx + TASKDATA.pid]
1670
        DEBUGF  1,"SOCKET_block: suspending thread: %u\n", edx
1671
        mov     [eax + SOCKET.TID], edx
3257 hidnplayr 1672
        pop     edx
1673
 
1674
        call    change_task
1675
        popf
1676
 
1677
        DEBUGF  1,"SOCKET_block: continueing\n"
1678
 
1679
        ret
1680
 
1681
 
1682
;-----------------------------------------------------------------
1683
;
1684
; SOCKET_notify
1685
;
1514 hidnplayr 1686
; notify's the owner of a socket that something happened
1687
;
1688
;  IN:  eax = socket ptr
1689
;  OUT: /
1690
;
1691
;-----------------------------------------------------------------
1692
align 4
3257 hidnplayr 1693
SOCKET_notify:
1514 hidnplayr 1694
 
3257 hidnplayr 1695
        DEBUGF  1,"SOCKET_notify: %x\n", eax
1514 hidnplayr 1696
 
2402 hidnplayr 1697
        call    SOCKET_check
1698
        jz      .error
1514 hidnplayr 1699
 
3257 hidnplayr 1700
        test    [eax + SOCKET.state], SS_BLOCKED
1701
        jnz     .unblock
1702
 
1703
        test    [eax + SOCKET.options], SO_NONBLOCK
1704
        jz      .error
1705
 
2402 hidnplayr 1706
        push    eax ecx esi
1514 hidnplayr 1707
 
3257 hidnplayr 1708
; socket exists and is of non blocking type.
1709
; We'll try to flag an event to the thread
1514 hidnplayr 1710
 
3264 hidnplayr 1711
        mov     eax, [eax + SOCKET.TID]
2629 hidnplayr 1712
        test    eax, eax
3257 hidnplayr 1713
        jz      .done
2402 hidnplayr 1714
        mov     ecx, 1
1715
        mov     esi, TASK_DATA + TASKDATA.pid
1206 hidnplayr 1716
 
3257 hidnplayr 1717
  .next_pid:
2402 hidnplayr 1718
        cmp     [esi], eax
1719
        je      .found_pid
1720
        inc     ecx
1721
        add     esi, 0x20
1722
        cmp     ecx, [TASK_COUNT]
1723
        jbe     .next_pid
1514 hidnplayr 1724
; PID not found, TODO: close socket!
3257 hidnplayr 1725
        jmp     .done
1514 hidnplayr 1726
 
3257 hidnplayr 1727
  .found_pid:
2402 hidnplayr 1728
        shl     ecx, 8
1729
        or      [ecx + SLOT_BASE + APPDATA.event_mask], EVENT_NETWORK
3257 hidnplayr 1730
        mov     [check_idle_semaphore], 200                             ; What does this mean??
1206 hidnplayr 1731
 
3257 hidnplayr 1732
        DEBUGF  1,"SOCKET_notify: Raised a network event!\n"
1514 hidnplayr 1733
 
3257 hidnplayr 1734
        jmp     .done
1735
 
1736
  .unblock:
1737
        push    eax ecx esi
1738
        ; Clear the 'socket is blocked' flag
1739
        and     [eax + SOCKET.state], not SS_BLOCKED
1740
 
1741
        ; Find the thread's TASK_DATA
3264 hidnplayr 1742
        mov     eax, [eax + SOCKET.TID]
3257 hidnplayr 1743
        test    eax, eax
1744
        jz      .error
1745
        xor     ecx, ecx
1746
        inc     ecx
1747
        mov     esi, TASK_DATA
1748
  .next:
1749
        cmp     [esi + TASKDATA.pid], eax
1750
        je      .found
1751
        inc     ecx
1752
        add     esi, 0x20
1753
        cmp     ecx, [TASK_COUNT]
1754
        jbe     .next
1755
        jmp     .error
1756
  .found:
1757
 
1758
        ; Run the thread
1759
        mov     [esi + TASKDATA.state], 0       ; Running
1760
        DEBUGF  1,"SOCKET_notify: Unblocked socket!\n"
1761
 
1762
  .done:
2402 hidnplayr 1763
        pop     esi ecx eax
1536 hidnplayr 1764
 
1514 hidnplayr 1765
  .error:
2402 hidnplayr 1766
        ret
1206 hidnplayr 1767
 
1768
 
1514 hidnplayr 1769
;--------------------------------------------------------------------
1770
;
1771
; SOCKET_alloc
1772
;
1159 hidnplayr 1773
; Allocate memory for socket data and put new socket into the list
1774
; Newly created socket is initialized with calling PID and number and
1775
; put into beginning of list (which is a fastest way).
1776
;
1514 hidnplayr 1777
; IN:  /
1778
; OUT: eax = 0 on error, socket ptr otherwise
1779
;      edi = socket number
1780
;       ZF = cleared on error
1159 hidnplayr 1781
;
1514 hidnplayr 1782
;--------------------------------------------------------------------
1783
align 4
1784
SOCKET_alloc:
1785
 
2402 hidnplayr 1786
        push    ebx
1514 hidnplayr 1787
 
2402 hidnplayr 1788
        stdcall kernel_alloc, SOCKETBUFFSIZE
1789
        DEBUGF  1, "SOCKET_alloc: ptr=%x\n", eax
1790
        or      eax, eax
1791
        jz      .exit
1159 hidnplayr 1792
 
1514 hidnplayr 1793
; zero-initialize allocated memory
2402 hidnplayr 1794
        push    eax
1795
        mov     edi, eax
1796
        mov     ecx, SOCKETBUFFSIZE / 4
1797
        xor     eax, eax
1798
        rep     stosd
1799
        pop     eax
1159 hidnplayr 1800
 
1536 hidnplayr 1801
; set send-and receive procedures to return -1
2402 hidnplayr 1802
        mov     [eax + SOCKET.snd_proc], s_error
1803
        mov     [eax + SOCKET.rcv_proc], s_error
1536 hidnplayr 1804
 
1514 hidnplayr 1805
; find first free socket number and use it
2402 hidnplayr 1806
        mov     edi, [last_socket_num]
1159 hidnplayr 1807
  .next_socket_number:
2402 hidnplayr 1808
        inc     edi
1809
        jz      .next_socket_number     ; avoid socket nr 0
1810
        cmp     edi, -1
1811
        je      .next_socket_number     ; avoid socket nr -1
1812
        mov     ebx, net_sockets
1159 hidnplayr 1813
  .next_socket:
2402 hidnplayr 1814
        mov     ebx, [ebx + SOCKET.NextPtr]
1815
        test    ebx, ebx
1816
        jz      .last_socket
1536 hidnplayr 1817
 
2402 hidnplayr 1818
        cmp     [ebx + SOCKET.Number], edi
1819
        jne     .next_socket
1820
        jmp     .next_socket_number
1159 hidnplayr 1821
 
1514 hidnplayr 1822
  .last_socket:
2402 hidnplayr 1823
        mov     [last_socket_num], edi
1824
        mov     [eax + SOCKET.Number], edi
1825
        DEBUGF  1, "SOCKET_alloc: number=%u\n", edi
1159 hidnplayr 1826
 
1514 hidnplayr 1827
; Fill in PID
2402 hidnplayr 1828
        mov     ebx, [TASK_BASE]
1829
        mov     ebx, [ebx + TASKDATA.pid]
1830
        mov     [eax + SOCKET.PID], ebx
3264 hidnplayr 1831
        mov     [eax + SOCKET.TID], ebx         ; currently TID = PID in kolibrios :(
1514 hidnplayr 1832
 
2403 hidnplayr 1833
; init mutex
1834
        pusha
1835
        lea     ecx, [eax + SOCKET.mutex]
1836
        call    mutex_init
1837
        popa
1838
 
1529 hidnplayr 1839
; add socket to the list by re-arranging some pointers
2402 hidnplayr 1840
        mov     ebx, [net_sockets + SOCKET.NextPtr]
1514 hidnplayr 1841
 
2402 hidnplayr 1842
        mov     [eax + SOCKET.PrevPtr], net_sockets
1843
        mov     [eax + SOCKET.NextPtr], ebx
1514 hidnplayr 1844
 
2402 hidnplayr 1845
        test    ebx, ebx
1846
        jz      @f
1847
 
1848
        pusha
1849
        lea     ecx, [ebx + SOCKET.mutex]
1850
        call    mutex_lock
1851
        popa
1852
 
1853
        mov     [ebx + SOCKET.PrevPtr], eax
1854
 
1855
        pusha
1856
        lea     ecx, [ebx + SOCKET.mutex]
1857
        call    mutex_unlock
1858
        popa
1514 hidnplayr 1859
       @@:
1860
 
2402 hidnplayr 1861
        mov     [net_sockets + SOCKET.NextPtr], eax
1862
        or      eax, eax                ; used to clear zero flag
1159 hidnplayr 1863
  .exit:
2402 hidnplayr 1864
        pop     ebx
1514 hidnplayr 1865
 
2402 hidnplayr 1866
        ret
1159 hidnplayr 1867
 
1514 hidnplayr 1868
 
1869
;----------------------------------------------------
1159 hidnplayr 1870
;
1514 hidnplayr 1871
; SOCKET_free
1159 hidnplayr 1872
;
1514 hidnplayr 1873
; Free socket data memory and remove socket from the list
1874
;
1875
; IN:  eax = socket ptr
1876
; OUT: /
1877
;
1878
;----------------------------------------------------
1879
align 4
1880
SOCKET_free:
1159 hidnplayr 1881
 
2402 hidnplayr 1882
        DEBUGF  1, "SOCKET_free: %x\n", eax
1514 hidnplayr 1883
 
2402 hidnplayr 1884
        call    SOCKET_check
1885
        jz      .error
1159 hidnplayr 1886
 
2402 hidnplayr 1887
        push    ebx
1514 hidnplayr 1888
 
2402 hidnplayr 1889
        pusha
1890
        lea     ecx, [eax + SOCKET.mutex]
1891
        call    mutex_lock
1892
        popa
1514 hidnplayr 1893
 
2402 hidnplayr 1894
        cmp     [eax + SOCKET.Domain], AF_INET4
1895
        jnz     .no_tcp
1529 hidnplayr 1896
 
2402 hidnplayr 1897
        cmp     [eax + SOCKET.Protocol], IP_PROTO_TCP
1898
        jnz     .no_tcp
1899
 
1900
        mov     ebx, eax
1901
        stdcall kernel_free, [ebx + STREAM_SOCKET.rcv.start_ptr]
1902
        stdcall kernel_free, [ebx + STREAM_SOCKET.snd.start_ptr]
1903
        mov     eax, ebx
1536 hidnplayr 1904
  .no_tcp:
1529 hidnplayr 1905
 
2402 hidnplayr 1906
        push    eax                             ; this will be passed to kernel_free
1907
        mov     ebx, [eax + SOCKET.NextPtr]
1908
        mov     eax, [eax + SOCKET.PrevPtr]
1514 hidnplayr 1909
 
2402 hidnplayr 1910
        DEBUGF  1, "SOCKET_free: linking socket %x to socket %x\n", eax, ebx
1514 hidnplayr 1911
 
2402 hidnplayr 1912
        test    eax, eax
1913
        jz      @f
1914
        mov     [eax + SOCKET.NextPtr], ebx
1514 hidnplayr 1915
       @@:
1159 hidnplayr 1916
 
2402 hidnplayr 1917
        test    ebx, ebx
1918
        jz      @f
1919
        mov     [ebx + SOCKET.PrevPtr], eax
1514 hidnplayr 1920
       @@:
1249 hidnplayr 1921
 
2402 hidnplayr 1922
        call    kernel_free
1923
        pop     ebx
1159 hidnplayr 1924
 
2402 hidnplayr 1925
        DEBUGF  1, "SOCKET_free: success!\n"
1514 hidnplayr 1926
 
1159 hidnplayr 1927
  .error:
2402 hidnplayr 1928
        ret
1159 hidnplayr 1929
 
1543 hidnplayr 1930
;------------------------------------
1931
;
1932
; SOCKET_fork
1933
;
1934
; Create a child socket
1935
;
1533 hidnplayr 1936
; IN:  socket nr in ebx
1543 hidnplayr 1937
; OUT: child socket nr in eax
1938
;
1939
;-----------------------------------
1529 hidnplayr 1940
align 4
1941
SOCKET_fork:
1942
 
2402 hidnplayr 1943
        DEBUGF  1,"SOCKET_fork: %x\n", ebx
1529 hidnplayr 1944
 
1543 hidnplayr 1945
; Exit if backlog queue is full
2402 hidnplayr 1946
        mov     eax, [ebx + SOCKET_QUEUE_LOCATION + queue.size]
1947
        cmp     ax, [ebx + SOCKET.backlog]
1948
        jae     .fail
1543 hidnplayr 1949
 
1529 hidnplayr 1950
; Allocate new socket
2402 hidnplayr 1951
        push    ebx
1952
        call    SOCKET_alloc
1953
        pop     ebx
1954
        jz      .fail
1529 hidnplayr 1955
 
2402 hidnplayr 1956
        push    eax
1957
        mov     esi, esp
1958
        add_to_queue (ebx + SOCKET_QUEUE_LOCATION), MAX_backlog, 4, .fail2
1959
        pop     eax
1543 hidnplayr 1960
 
1961
; Copy structure from current socket to new
1962
; We start at PID to preserve the socket num, and the 2 pointers at beginning of socket
2402 hidnplayr 1963
        lea     esi, [ebx + SOCKET.PID]
1964
        lea     edi, [eax + SOCKET.PID]
1965
        mov     ecx, (SOCKET_QUEUE_LOCATION - SOCKET.PID + 3)/4
1966
        rep     movsd
1529 hidnplayr 1967
 
2402 hidnplayr 1968
        and     [eax + SOCKET.options], not SO_ACCEPTCON
1529 hidnplayr 1969
 
2402 hidnplayr 1970
        ret
1529 hidnplayr 1971
 
1543 hidnplayr 1972
  .fail2:
2402 hidnplayr 1973
        add     esp, 4+4+4
1543 hidnplayr 1974
  .fail:
2402 hidnplayr 1975
        DEBUGF  1,"SOCKET_fork: failed\n"
1976
        xor     eax, eax
1977
        ret
1529 hidnplayr 1978
 
1543 hidnplayr 1979
 
1514 hidnplayr 1980
;---------------------------------------------------
1981
;
1982
; SOCKET_num_to_ptr
1983
;
1159 hidnplayr 1984
; Get socket structure address by its number
1985
;
1514 hidnplayr 1986
; IN:  ecx = socket number
1533 hidnplayr 1987
; OUT: eax = 0 on error, socket ptr otherwise
1514 hidnplayr 1988
;       ZF = set on error
1159 hidnplayr 1989
;
1514 hidnplayr 1990
;---------------------------------------------------
1991
align 4
1992
SOCKET_num_to_ptr:
1159 hidnplayr 1993
 
2891 hidnplayr 1994
        DEBUGF  1,"SOCKET_num_to_ptr: num=%u ", ecx
1514 hidnplayr 1995
 
2402 hidnplayr 1996
        mov     eax, net_sockets
1514 hidnplayr 1997
 
1159 hidnplayr 1998
  .next_socket:
2402 hidnplayr 1999
        mov     eax, [eax + SOCKET.NextPtr]
2000
        or      eax, eax
2001
        jz      .error
2002
        cmp     [eax + SOCKET.Number], ecx
2003
        jne     .next_socket
1159 hidnplayr 2004
 
2402 hidnplayr 2005
        test    eax, eax
1159 hidnplayr 2006
 
2891 hidnplayr 2007
        DEBUGF  1,"ptr=%x\n", eax
2008
        ret
2009
 
1159 hidnplayr 2010
  .error:
2891 hidnplayr 2011
        DEBUGF  1,"not found\n", eax
2402 hidnplayr 2012
        ret
1159 hidnplayr 2013
 
1514 hidnplayr 2014
 
2015
;---------------------------------------------------
1159 hidnplayr 2016
;
1514 hidnplayr 2017
; SOCKET_ptr_to_num
1159 hidnplayr 2018
;
1514 hidnplayr 2019
; Get socket number by its address
2020
;
2021
; IN:  eax = socket ptr
2022
; OUT: eax = 0 on error, socket num otherwise
2023
;       ZF = set on error
2024
;
2025
;---------------------------------------------------
2026
align 4
2027
SOCKET_ptr_to_num:
2028
 
2891 hidnplayr 2029
        DEBUGF  1,"SOCKET_ptr_to_num: ptr=%x ", eax
1514 hidnplayr 2030
 
2402 hidnplayr 2031
        call    SOCKET_check
2032
        jz      .error
1159 hidnplayr 2033
 
2402 hidnplayr 2034
        mov     eax, [eax + SOCKET.Number]
1514 hidnplayr 2035
 
2891 hidnplayr 2036
        DEBUGF  1,"num=%u\n", eax
2037
        ret
1514 hidnplayr 2038
 
2039
  .error:
2891 hidnplayr 2040
        DEBUGF  1,"not found\n", eax
2402 hidnplayr 2041
        ret
1514 hidnplayr 2042
 
2043
 
2044
;---------------------------------------------------
2045
;
2046
; SOCKET_check
2047
;
2048
; checks if the given value is really a socket ptr
2049
;
2050
; IN:  eax = socket ptr
2051
; OUT: eax = 0 on error, unchanged otherwise
2052
;       ZF = set on error
2053
;
2054
;---------------------------------------------------
2055
align 4
2056
SOCKET_check:
2057
 
2402 hidnplayr 2058
        DEBUGF  1,"SOCKET_check: %x\n", eax
1514 hidnplayr 2059
 
2402 hidnplayr 2060
        push    ebx
2061
        mov     ebx, net_sockets
1514 hidnplayr 2062
 
1159 hidnplayr 2063
  .next_socket:
2402 hidnplayr 2064
        mov     ebx, [ebx + SOCKET.NextPtr]
2065
        or      ebx, ebx
2066
        jz      .done
2067
        cmp     ebx, eax
2068
        jnz     .next_socket
1159 hidnplayr 2069
 
1514 hidnplayr 2070
  .done:
2402 hidnplayr 2071
        mov     eax, ebx
2072
        test    eax, eax
2073
        pop     ebx
1514 hidnplayr 2074
 
2402 hidnplayr 2075
        ret
1159 hidnplayr 2076
 
1514 hidnplayr 2077
 
2078
 
2079
;---------------------------------------------------
2080
;
2081
; SOCKET_check_owner
2082
;
2083
; checks if the caller application owns the socket
2084
;
2085
; IN:  eax = socket ptr
2086
; OUT:  ZF = true/false
2087
;
2088
;---------------------------------------------------
2089
align 4
2090
SOCKET_check_owner:
2091
 
2402 hidnplayr 2092
        DEBUGF  1,"SOCKET_check_owner: %x\n", eax
1514 hidnplayr 2093
 
2402 hidnplayr 2094
        push    ebx
2095
        mov     ebx, [TASK_BASE]
3257 hidnplayr 2096
        mov     ebx, [ebx + TASKDATA.pid]
2402 hidnplayr 2097
        cmp     [eax + SOCKET.PID], ebx
2098
        pop      ebx
1514 hidnplayr 2099
 
2402 hidnplayr 2100
        ret
1514 hidnplayr 2101
 
2102
 
2103
 
2104
 
1885 hidnplayr 2105
;------------------------------------------------------
1514 hidnplayr 2106
;
2107
; SOCKET_process_end
2108
;
2109
; Kernel calls this function when a certain process ends
2110
; This function will check if the process had any open sockets
2111
; And update them accordingly
2112
;
2867 hidnplayr 2113
; IN:  edx = pid
1514 hidnplayr 2114
; OUT: /
2115
;
2116
;------------------------------------------------------
2117
align 4
2118
SOCKET_process_end:
2119
 
3264 hidnplayr 2120
        DEBUGF  1, "SOCKET_process_end: %x\n", edx
1514 hidnplayr 2121
 
2402 hidnplayr 2122
        push    ebx
2123
        mov     ebx, net_sockets
1514 hidnplayr 2124
 
2125
  .next_socket:
2402 hidnplayr 2126
        mov     ebx, [ebx + SOCKET.NextPtr]
3307 hidnplayr 2127
  .next_socket_test:
2402 hidnplayr 2128
        test    ebx, ebx
2129
        jz      .done
1514 hidnplayr 2130
 
2867 hidnplayr 2131
        cmp     [ebx + SOCKET.PID], edx
2402 hidnplayr 2132
        jne     .next_socket
1514 hidnplayr 2133
 
3264 hidnplayr 2134
        DEBUGF  1, "SOCKET_process_end: killing socket %x\n", ebx
1514 hidnplayr 2135
 
2402 hidnplayr 2136
        mov     [ebx + SOCKET.PID], 0
2137
        mov     eax, ebx
3307 hidnplayr 2138
        mov     ebx, [ebx + SOCKET.NextPtr]
3264 hidnplayr 2139
        pusha
2140
        call    SOCKET_close.socket
2141
        popa
3307 hidnplayr 2142
        jmp     .next_socket_test
1514 hidnplayr 2143
 
2144
  .done:
2402 hidnplayr 2145
        pop     ebx
1514 hidnplayr 2146
 
2402 hidnplayr 2147
        ret
1773 hidnplayr 2148
 
2149
 
2150
 
2151
 
1885 hidnplayr 2152
;-----------------------------------------------------------------
2153
;
2154
; SOCKET_is_connecting
2155
;
2156
;  IN:  eax = socket ptr
2157
;  OUT: /
2158
;
2159
;-----------------------------------------------------------------
1773 hidnplayr 2160
 
1885 hidnplayr 2161
align 4
2162
SOCKET_is_connecting:
1773 hidnplayr 2163
 
2891 hidnplayr 2164
        DEBUGF  1,"SOCKET_is_connecting: %x\n", eax
1773 hidnplayr 2165
 
2402 hidnplayr 2166
        and     [eax + SOCKET.options], not (SS_ISCONNECTED + SS_ISDISCONNECTING + SS_ISCONFIRMING)
2167
        or      [eax + SOCKET.options], SS_ISCONNECTING
1773 hidnplayr 2168
 
3257 hidnplayr 2169
        jmp     SOCKET_notify
1885 hidnplayr 2170
 
2171
 
2172
 
1773 hidnplayr 2173
;-----------------------------------------------------------------
2174
;
1885 hidnplayr 2175
; SOCKET_is_connected
2176
;
2177
;  IN:  eax = socket ptr
2178
;  OUT: /
2179
;
2180
;-----------------------------------------------------------------
2181
 
2182
align 4
2183
SOCKET_is_connected:
2184
 
2891 hidnplayr 2185
        DEBUGF  1,"SOCKET_is_connected: %x\n", eax
1885 hidnplayr 2186
 
2402 hidnplayr 2187
        and     [eax + SOCKET.options], not (SS_ISCONNECTING + SS_ISDISCONNECTING + SS_ISCONFIRMING)
2188
        or      [eax + SOCKET.options], SS_ISCONNECTED
1885 hidnplayr 2189
 
3257 hidnplayr 2190
        jmp     SOCKET_notify
1885 hidnplayr 2191
 
2192
 
2193
 
2194
 
2195
;-----------------------------------------------------------------
2196
;
1773 hidnplayr 2197
; SOCKET_is_disconnecting
2198
;
2199
;  IN:  eax = socket ptr
2200
;  OUT: /
2201
;
2202
;-----------------------------------------------------------------
2203
 
2204
align 4
2205
SOCKET_is_disconnecting:
2206
 
2891 hidnplayr 2207
        DEBUGF  1,"SOCKET_is_disconnecting: %x\n", eax
2208
 
2402 hidnplayr 2209
        and     [eax + SOCKET.options], not (SS_ISCONNECTING)
2210
        or      [eax + SOCKET.options], SS_ISDISCONNECTING + SS_CANTRCVMORE + SS_CANTSENDMORE
1773 hidnplayr 2211
 
3257 hidnplayr 2212
        jmp     SOCKET_notify
1773 hidnplayr 2213
 
2214
 
2215
 
2216
;-----------------------------------------------------------------
2217
;
2218
; SOCKET_is_disconnected
2219
;
2220
;  IN:  eax = socket ptr
2221
;  OUT: /
2222
;
2223
;-----------------------------------------------------------------
2224
 
2225
align 4
2226
SOCKET_is_disconnected:
2227
 
2891 hidnplayr 2228
        DEBUGF  1,"SOCKET_is_disconnected: %x\n", eax
2229
 
2402 hidnplayr 2230
        and     [eax + SOCKET.options], not (SS_ISCONNECTING + SS_ISCONNECTED + SS_ISDISCONNECTING)
2231
        or      [eax + SOCKET.options], SS_CANTRCVMORE + SS_CANTSENDMORE
1773 hidnplayr 2232
 
3257 hidnplayr 2233
        jmp     SOCKET_notify
1774 hidnplayr 2234
 
2235
 
2236
;-----------------------------------------------------------------
2237
;
2238
; SOCKET_cant_recv_more
2239
;
2240
;  IN:  eax = socket ptr
2241
;  OUT: /
2242
;
2243
;-----------------------------------------------------------------
2244
 
2245
align 4
2246
SOCKET_cant_recv_more:
2247
 
2891 hidnplayr 2248
        DEBUGF  1,"SOCKET_cant_recv_more: %x\n", eax
2249
 
2402 hidnplayr 2250
        or      [eax + SOCKET.options], SS_CANTRCVMORE
1885 hidnplayr 2251
 
2402 hidnplayr 2252
        ret
1831 hidnplayr 2253
 
2254
 
2255
 
2256
;-----------------------------------------------------------------
2257
;
1885 hidnplayr 2258
; SOCKET_cant_send_more
1831 hidnplayr 2259
;
2260
;  IN:  eax = socket ptr
2261
;  OUT: /
2262
;
2263
;-----------------------------------------------------------------
2264
 
2265
align 4
1885 hidnplayr 2266
SOCKET_cant_send_more:
1831 hidnplayr 2267
 
2891 hidnplayr 2268
        DEBUGF  1,"SOCKET_cant_send_more: %x\n", eax
2269
 
2402 hidnplayr 2270
        or      [eax + SOCKET.options], SS_CANTSENDMORE
1831 hidnplayr 2271
 
2402 hidnplayr 2272
        ret