Subversion Repositories Kolibri OS

Rev

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