Subversion Repositories Kolibri OS

Rev

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

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