Subversion Repositories Kolibri OS

Rev

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