Subversion Repositories Kolibri OS

Rev

Rev 2937 | 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: 2939 $
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
        mov     ecx, esi
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"
2402 hidnplayr 1351
        ret
1529 hidnplayr 1352
 
1533 hidnplayr 1353
  .less_data:
2893 hidnplayr 1354
        mov     ecx, edx
2402 hidnplayr 1355
        jmp     .copy
1529 hidnplayr 1356
 
1357
 
1358
;-----------------------------------------------------------------
1359
;
1360
; SOCKET_ring_free
1361
;
1362
; Free's some bytes from the ringbuffer
1363
;
1364
;  IN:  eax = ptr to ring struct
1365
;       ecx = data size
1366
;
1367
;  OUT: ecx = number of bytes free-ed
1368
;
1369
;-----------------------------------------------------------------
1370
align 4
1371
SOCKET_ring_free:
1372
 
2402 hidnplayr 1373
        DEBUGF  1,"SOCKET_ring_free: %u bytes from ring %x\n", ecx, eax
1529 hidnplayr 1374
 
2402 hidnplayr 1375
        sub     [eax + RING_BUFFER.size], ecx
2888 hidnplayr 1376
        jb      .error
2402 hidnplayr 1377
        add     [eax + RING_BUFFER.read_ptr], ecx
1529 hidnplayr 1378
 
2402 hidnplayr 1379
        mov     edx, [eax + RING_BUFFER.end_ptr]
1380
        cmp     [eax + RING_BUFFER.read_ptr], edx
1381
        jb      @f
1382
        sub     [eax + RING_BUFFER.read_ptr], SOCKET_MAXDATA
1529 hidnplayr 1383
       @@:
2402 hidnplayr 1384
        ret
1529 hidnplayr 1385
 
2888 hidnplayr 1386
  .error:       ; we could free all available bytes, but that would be stupid, i guess..
1387
        DEBUGF  1,"SOCKET_ring_free: buffer=%x error!\n", eax
2402 hidnplayr 1388
        add     [eax + RING_BUFFER.size], ecx
1389
        xor     ecx, ecx
1390
        ret
1529 hidnplayr 1391
 
1392
 
1393
;-----------------------------------------------------------------
1394
;
1514 hidnplayr 1395
; SOCKET_notify_owner
1396
;
1397
; notify's the owner of a socket that something happened
1398
;
1399
;  IN:  eax = socket ptr
1400
;  OUT: /
1401
;
1402
;-----------------------------------------------------------------
1403
align 4
1404
SOCKET_notify_owner:
1405
 
2402 hidnplayr 1406
        DEBUGF  1,"SOCKET_notify_owner: %x\n", eax
1514 hidnplayr 1407
 
2402 hidnplayr 1408
        call    SOCKET_check
1409
        jz      .error
1514 hidnplayr 1410
 
2402 hidnplayr 1411
        push    eax ecx esi
1514 hidnplayr 1412
 
1413
; socket exists, now try to flag an event to the application
1414
 
2402 hidnplayr 1415
        mov     eax, [eax + SOCKET.PID]
2629 hidnplayr 1416
        test    eax, eax
1417
        jz      .error2
2402 hidnplayr 1418
        mov     ecx, 1
1419
        mov     esi, TASK_DATA + TASKDATA.pid
1206 hidnplayr 1420
 
1421
       .next_pid:
2402 hidnplayr 1422
        cmp     [esi], eax
1423
        je      .found_pid
1424
        inc     ecx
1425
        add     esi, 0x20
1426
        cmp     ecx, [TASK_COUNT]
1427
        jbe     .next_pid
1206 hidnplayr 1428
 
1514 hidnplayr 1429
; PID not found, TODO: close socket!
1430
 
2402 hidnplayr 1431
        jmp     .error2
1514 hidnplayr 1432
 
1206 hidnplayr 1433
       .found_pid:
2402 hidnplayr 1434
        shl     ecx, 8
1435
        or      [ecx + SLOT_BASE + APPDATA.event_mask], EVENT_NETWORK
1436
        mov     [check_idle_semaphore], 200
1206 hidnplayr 1437
 
2402 hidnplayr 1438
        DEBUGF  1,"SOCKET_notify_owner: succes!\n"
1514 hidnplayr 1439
 
1440
  .error2:
2402 hidnplayr 1441
        pop     esi ecx eax
1536 hidnplayr 1442
 
1514 hidnplayr 1443
  .error:
1444
 
2402 hidnplayr 1445
        ret
1206 hidnplayr 1446
 
1447
 
1514 hidnplayr 1448
;--------------------------------------------------------------------
1449
;
1450
; SOCKET_alloc
1451
;
1159 hidnplayr 1452
; Allocate memory for socket data and put new socket into the list
1453
; Newly created socket is initialized with calling PID and number and
1454
; put into beginning of list (which is a fastest way).
1455
;
1514 hidnplayr 1456
; IN:  /
1457
; OUT: eax = 0 on error, socket ptr otherwise
1458
;      edi = socket number
1459
;       ZF = cleared on error
1159 hidnplayr 1460
;
1514 hidnplayr 1461
;--------------------------------------------------------------------
1462
align 4
1463
SOCKET_alloc:
1464
 
2402 hidnplayr 1465
        push    ebx
1514 hidnplayr 1466
 
2402 hidnplayr 1467
        stdcall kernel_alloc, SOCKETBUFFSIZE
1468
        DEBUGF  1, "SOCKET_alloc: ptr=%x\n", eax
1469
        or      eax, eax
1470
        jz      .exit
1159 hidnplayr 1471
 
1514 hidnplayr 1472
; zero-initialize allocated memory
2402 hidnplayr 1473
        push    eax
1474
        mov     edi, eax
1475
        mov     ecx, SOCKETBUFFSIZE / 4
1476
        xor     eax, eax
1477
        rep     stosd
1478
        pop     eax
1159 hidnplayr 1479
 
1536 hidnplayr 1480
; set send-and receive procedures to return -1
2402 hidnplayr 1481
        mov     [eax + SOCKET.snd_proc], s_error
1482
        mov     [eax + SOCKET.rcv_proc], s_error
1536 hidnplayr 1483
 
1514 hidnplayr 1484
; find first free socket number and use it
2402 hidnplayr 1485
        mov     edi, [last_socket_num]
1159 hidnplayr 1486
  .next_socket_number:
2402 hidnplayr 1487
        inc     edi
1488
        jz      .next_socket_number     ; avoid socket nr 0
1489
        cmp     edi, -1
1490
        je      .next_socket_number     ; avoid socket nr -1
1491
        mov     ebx, net_sockets
1159 hidnplayr 1492
  .next_socket:
2402 hidnplayr 1493
        mov     ebx, [ebx + SOCKET.NextPtr]
1494
        test    ebx, ebx
1495
        jz      .last_socket
1536 hidnplayr 1496
 
2402 hidnplayr 1497
        cmp     [ebx + SOCKET.Number], edi
1498
        jne     .next_socket
1499
        jmp     .next_socket_number
1159 hidnplayr 1500
 
1514 hidnplayr 1501
  .last_socket:
2402 hidnplayr 1502
        mov     [last_socket_num], edi
1503
        mov     [eax + SOCKET.Number], edi
1504
        DEBUGF  1, "SOCKET_alloc: number=%u\n", edi
1159 hidnplayr 1505
 
1514 hidnplayr 1506
; Fill in PID
2402 hidnplayr 1507
        mov     ebx, [TASK_BASE]
1508
        mov     ebx, [ebx + TASKDATA.pid]
1509
        mov     [eax + SOCKET.PID], ebx
1514 hidnplayr 1510
 
2403 hidnplayr 1511
; init mutex
1512
        pusha
1513
        lea     ecx, [eax + SOCKET.mutex]
1514
        call    mutex_init
1515
        popa
1516
 
1529 hidnplayr 1517
; add socket to the list by re-arranging some pointers
2402 hidnplayr 1518
        mov     ebx, [net_sockets + SOCKET.NextPtr]
1514 hidnplayr 1519
 
2402 hidnplayr 1520
        mov     [eax + SOCKET.PrevPtr], net_sockets
1521
        mov     [eax + SOCKET.NextPtr], ebx
1514 hidnplayr 1522
 
2402 hidnplayr 1523
        test    ebx, ebx
1524
        jz      @f
1525
 
1526
        pusha
1527
        lea     ecx, [ebx + SOCKET.mutex]
1528
        call    mutex_lock
1529
        popa
1530
 
1531
        mov     [ebx + SOCKET.PrevPtr], eax
1532
 
1533
        pusha
1534
        lea     ecx, [ebx + SOCKET.mutex]
1535
        call    mutex_unlock
1536
        popa
1514 hidnplayr 1537
       @@:
1538
 
2402 hidnplayr 1539
        mov     [net_sockets + SOCKET.NextPtr], eax
1540
        or      eax, eax                ; used to clear zero flag
1159 hidnplayr 1541
  .exit:
2402 hidnplayr 1542
        pop     ebx
1514 hidnplayr 1543
 
2402 hidnplayr 1544
        ret
1159 hidnplayr 1545
 
1514 hidnplayr 1546
 
1547
;----------------------------------------------------
1159 hidnplayr 1548
;
1514 hidnplayr 1549
; SOCKET_free
1159 hidnplayr 1550
;
1514 hidnplayr 1551
; Free socket data memory and remove socket from the list
1552
;
1553
; IN:  eax = socket ptr
1554
; OUT: /
1555
;
1556
;----------------------------------------------------
1557
align 4
1558
SOCKET_free:
1159 hidnplayr 1559
 
2402 hidnplayr 1560
        DEBUGF  1, "SOCKET_free: %x\n", eax
1514 hidnplayr 1561
 
2402 hidnplayr 1562
        call    SOCKET_check
1563
        jz      .error
1159 hidnplayr 1564
 
2402 hidnplayr 1565
        push    ebx
1514 hidnplayr 1566
 
2402 hidnplayr 1567
        pusha
1568
        lea     ecx, [eax + SOCKET.mutex]
1569
        call    mutex_lock
1570
        popa
1514 hidnplayr 1571
 
2402 hidnplayr 1572
        cmp     [eax + SOCKET.Domain], AF_INET4
1573
        jnz     .no_tcp
1529 hidnplayr 1574
 
2402 hidnplayr 1575
        cmp     [eax + SOCKET.Protocol], IP_PROTO_TCP
1576
        jnz     .no_tcp
1577
 
1578
        mov     ebx, eax
1579
        stdcall kernel_free, [ebx + STREAM_SOCKET.rcv.start_ptr]
1580
        stdcall kernel_free, [ebx + STREAM_SOCKET.snd.start_ptr]
1581
        mov     eax, ebx
1536 hidnplayr 1582
  .no_tcp:
1529 hidnplayr 1583
 
2402 hidnplayr 1584
        push    eax                             ; this will be passed to kernel_free
1585
        mov     ebx, [eax + SOCKET.NextPtr]
1586
        mov     eax, [eax + SOCKET.PrevPtr]
1514 hidnplayr 1587
 
2402 hidnplayr 1588
        DEBUGF  1, "SOCKET_free: linking socket %x to socket %x\n", eax, ebx
1514 hidnplayr 1589
 
2402 hidnplayr 1590
        test    eax, eax
1591
        jz      @f
1592
        mov     [eax + SOCKET.NextPtr], ebx
1514 hidnplayr 1593
       @@:
1159 hidnplayr 1594
 
2402 hidnplayr 1595
        test    ebx, ebx
1596
        jz      @f
1597
        mov     [ebx + SOCKET.PrevPtr], eax
1514 hidnplayr 1598
       @@:
1249 hidnplayr 1599
 
2402 hidnplayr 1600
        call    kernel_free
1601
        pop     ebx
1159 hidnplayr 1602
 
2402 hidnplayr 1603
        DEBUGF  1, "SOCKET_free: success!\n"
1514 hidnplayr 1604
 
1159 hidnplayr 1605
  .error:
2402 hidnplayr 1606
        ret
1159 hidnplayr 1607
 
1543 hidnplayr 1608
;------------------------------------
1609
;
1610
; SOCKET_fork
1611
;
1612
; Create a child socket
1613
;
1533 hidnplayr 1614
; IN:  socket nr in ebx
1543 hidnplayr 1615
; OUT: child socket nr in eax
1616
;
1617
;-----------------------------------
1529 hidnplayr 1618
align 4
1619
SOCKET_fork:
1620
 
2402 hidnplayr 1621
        DEBUGF  1,"SOCKET_fork: %x\n", ebx
1529 hidnplayr 1622
 
1543 hidnplayr 1623
; Exit if backlog queue is full
2402 hidnplayr 1624
        mov     eax, [ebx + SOCKET_QUEUE_LOCATION + queue.size]
1625
        cmp     ax, [ebx + SOCKET.backlog]
1626
        jae     .fail
1543 hidnplayr 1627
 
1529 hidnplayr 1628
; Allocate new socket
2402 hidnplayr 1629
        push    ebx
1630
        call    SOCKET_alloc
1631
        pop     ebx
1632
        jz      .fail
1529 hidnplayr 1633
 
2402 hidnplayr 1634
        push    eax
1635
        mov     esi, esp
1636
        add_to_queue (ebx + SOCKET_QUEUE_LOCATION), MAX_backlog, 4, .fail2
1637
        pop     eax
1543 hidnplayr 1638
 
1639
; Copy structure from current socket to new
1640
; We start at PID to preserve the socket num, and the 2 pointers at beginning of socket
2402 hidnplayr 1641
        lea     esi, [ebx + SOCKET.PID]
1642
        lea     edi, [eax + SOCKET.PID]
1643
        mov     ecx, (SOCKET_QUEUE_LOCATION - SOCKET.PID + 3)/4
1644
        rep     movsd
1529 hidnplayr 1645
 
2402 hidnplayr 1646
        and     [eax + SOCKET.options], not SO_ACCEPTCON
1529 hidnplayr 1647
 
2402 hidnplayr 1648
        ret
1529 hidnplayr 1649
 
1543 hidnplayr 1650
  .fail2:
2402 hidnplayr 1651
        add     esp, 4+4+4
1543 hidnplayr 1652
  .fail:
2402 hidnplayr 1653
        DEBUGF  1,"SOCKET_fork: failed\n"
1654
        xor     eax, eax
1655
        ret
1529 hidnplayr 1656
 
1543 hidnplayr 1657
 
1514 hidnplayr 1658
;---------------------------------------------------
1659
;
1660
; SOCKET_num_to_ptr
1661
;
1159 hidnplayr 1662
; Get socket structure address by its number
1663
;
1514 hidnplayr 1664
; IN:  ecx = socket number
1533 hidnplayr 1665
; OUT: eax = 0 on error, socket ptr otherwise
1514 hidnplayr 1666
;       ZF = set on error
1159 hidnplayr 1667
;
1514 hidnplayr 1668
;---------------------------------------------------
1669
align 4
1670
SOCKET_num_to_ptr:
1159 hidnplayr 1671
 
2891 hidnplayr 1672
        DEBUGF  1,"SOCKET_num_to_ptr: num=%u ", ecx
1514 hidnplayr 1673
 
2402 hidnplayr 1674
        mov     eax, net_sockets
1514 hidnplayr 1675
 
1159 hidnplayr 1676
  .next_socket:
2402 hidnplayr 1677
        mov     eax, [eax + SOCKET.NextPtr]
1678
        or      eax, eax
1679
        jz      .error
1680
        cmp     [eax + SOCKET.Number], ecx
1681
        jne     .next_socket
1159 hidnplayr 1682
 
2402 hidnplayr 1683
        test    eax, eax
1159 hidnplayr 1684
 
2891 hidnplayr 1685
        DEBUGF  1,"ptr=%x\n", eax
1686
        ret
1687
 
1159 hidnplayr 1688
  .error:
2891 hidnplayr 1689
        DEBUGF  1,"not found\n", eax
2402 hidnplayr 1690
        ret
1159 hidnplayr 1691
 
1514 hidnplayr 1692
 
1693
;---------------------------------------------------
1159 hidnplayr 1694
;
1514 hidnplayr 1695
; SOCKET_ptr_to_num
1159 hidnplayr 1696
;
1514 hidnplayr 1697
; Get socket number by its address
1698
;
1699
; IN:  eax = socket ptr
1700
; OUT: eax = 0 on error, socket num otherwise
1701
;       ZF = set on error
1702
;
1703
;---------------------------------------------------
1704
align 4
1705
SOCKET_ptr_to_num:
1706
 
2891 hidnplayr 1707
        DEBUGF  1,"SOCKET_ptr_to_num: ptr=%x ", eax
1514 hidnplayr 1708
 
2402 hidnplayr 1709
        call    SOCKET_check
1710
        jz      .error
1159 hidnplayr 1711
 
2402 hidnplayr 1712
        mov     eax, [eax + SOCKET.Number]
1514 hidnplayr 1713
 
2891 hidnplayr 1714
        DEBUGF  1,"num=%u\n", eax
1715
        ret
1514 hidnplayr 1716
 
1717
  .error:
2891 hidnplayr 1718
        DEBUGF  1,"not found\n", eax
2402 hidnplayr 1719
        ret
1514 hidnplayr 1720
 
1721
 
1722
;---------------------------------------------------
1723
;
1724
; SOCKET_check
1725
;
1726
; checks if the given value is really a socket ptr
1727
;
1728
; IN:  eax = socket ptr
1729
; OUT: eax = 0 on error, unchanged otherwise
1730
;       ZF = set on error
1731
;
1732
;---------------------------------------------------
1733
align 4
1734
SOCKET_check:
1735
 
2402 hidnplayr 1736
        DEBUGF  1,"SOCKET_check: %x\n", eax
1514 hidnplayr 1737
 
2402 hidnplayr 1738
        push    ebx
1739
        mov     ebx, net_sockets
1514 hidnplayr 1740
 
1159 hidnplayr 1741
  .next_socket:
2402 hidnplayr 1742
        mov     ebx, [ebx + SOCKET.NextPtr]
1743
        or      ebx, ebx
1744
        jz      .done
1745
        cmp     ebx, eax
1746
        jnz     .next_socket
1159 hidnplayr 1747
 
1514 hidnplayr 1748
  .done:
2402 hidnplayr 1749
        mov     eax, ebx
1750
        test    eax, eax
1751
        pop     ebx
1514 hidnplayr 1752
 
2402 hidnplayr 1753
        ret
1159 hidnplayr 1754
 
1514 hidnplayr 1755
 
1756
 
1757
;---------------------------------------------------
1758
;
1759
; SOCKET_check_owner
1760
;
1761
; checks if the caller application owns the socket
1762
;
1763
; IN:  eax = socket ptr
1764
; OUT:  ZF = true/false
1765
;
1766
;---------------------------------------------------
1767
align 4
1768
SOCKET_check_owner:
1769
 
2402 hidnplayr 1770
        DEBUGF  1,"SOCKET_check_owner: %x\n", eax
1514 hidnplayr 1771
 
2402 hidnplayr 1772
        push    ebx
1773
        mov     ebx, [TASK_BASE]
1774
        mov     ebx, [ecx + TASKDATA.pid]
1775
        cmp     [eax + SOCKET.PID], ebx
1776
        pop      ebx
1514 hidnplayr 1777
 
2402 hidnplayr 1778
        ret
1514 hidnplayr 1779
 
1780
 
1781
 
1782
 
1885 hidnplayr 1783
;------------------------------------------------------
1514 hidnplayr 1784
;
1785
; SOCKET_process_end
1786
;
1787
; Kernel calls this function when a certain process ends
1788
; This function will check if the process had any open sockets
1789
; And update them accordingly
1790
;
2867 hidnplayr 1791
; IN:  edx = pid
1514 hidnplayr 1792
; OUT: /
1793
;
1794
;------------------------------------------------------
1795
align 4
1796
SOCKET_process_end:
1797
 
2867 hidnplayr 1798
        DEBUGF  1,"SOCKET_process_end: %x\n", edx
1514 hidnplayr 1799
 
2402 hidnplayr 1800
        push    ebx
1801
        mov     ebx, net_sockets
1514 hidnplayr 1802
 
1803
  .next_socket:
2402 hidnplayr 1804
        mov     ebx, [ebx + SOCKET.NextPtr]
1514 hidnplayr 1805
  .test_socket:
2402 hidnplayr 1806
        test    ebx, ebx
1807
        jz      .done
1514 hidnplayr 1808
 
2867 hidnplayr 1809
        cmp     [ebx + SOCKET.PID], edx
2402 hidnplayr 1810
        jne     .next_socket
1514 hidnplayr 1811
 
2891 hidnplayr 1812
        DEBUGF  1,"SOCKET_process_end: killing socket %x\n", ebx
1514 hidnplayr 1813
 
2402 hidnplayr 1814
        mov     [ebx + SOCKET.PID], 0
1514 hidnplayr 1815
 
2402 hidnplayr 1816
        cmp     [ebx + SOCKET.Protocol], IP_PROTO_TCP
1817
        je      .tcp
1514 hidnplayr 1818
 
2629 hidnplayr 1819
; The socket is stateless, just kill it right away!
1514 hidnplayr 1820
 
2402 hidnplayr 1821
        mov     eax, ebx
1822
        mov     ebx, [ebx + SOCKET.NextPtr]
1823
        call    SOCKET_free
1824
        jmp     .test_socket
1514 hidnplayr 1825
 
1826
  .tcp:
2629 hidnplayr 1827
        push    [ebx + SOCKET.NextPtr]
1828
        mov     eax, ebx
2869 hidnplayr 1829
        call    TCP_disconnect
2629 hidnplayr 1830
        pop     ebx
1831
        jmp     .test_socket
1885 hidnplayr 1832
 
1514 hidnplayr 1833
  .done:
2402 hidnplayr 1834
        pop     ebx
1514 hidnplayr 1835
 
2402 hidnplayr 1836
        ret
1773 hidnplayr 1837
 
1838
 
1839
 
1840
 
1885 hidnplayr 1841
;-----------------------------------------------------------------
1842
;
1843
; SOCKET_is_connecting
1844
;
1845
;  IN:  eax = socket ptr
1846
;  OUT: /
1847
;
1848
;-----------------------------------------------------------------
1773 hidnplayr 1849
 
1885 hidnplayr 1850
align 4
1851
SOCKET_is_connecting:
1773 hidnplayr 1852
 
2891 hidnplayr 1853
        DEBUGF  1,"SOCKET_is_connecting: %x\n", eax
1773 hidnplayr 1854
 
2402 hidnplayr 1855
        and     [eax + SOCKET.options], not (SS_ISCONNECTED + SS_ISDISCONNECTING + SS_ISCONFIRMING)
1856
        or      [eax + SOCKET.options], SS_ISCONNECTING
1773 hidnplayr 1857
 
2402 hidnplayr 1858
        jmp     SOCKET_notify_owner
1885 hidnplayr 1859
 
1860
 
1861
 
1773 hidnplayr 1862
;-----------------------------------------------------------------
1863
;
1885 hidnplayr 1864
; SOCKET_is_connected
1865
;
1866
;  IN:  eax = socket ptr
1867
;  OUT: /
1868
;
1869
;-----------------------------------------------------------------
1870
 
1871
align 4
1872
SOCKET_is_connected:
1873
 
2891 hidnplayr 1874
        DEBUGF  1,"SOCKET_is_connected: %x\n", eax
1885 hidnplayr 1875
 
2402 hidnplayr 1876
        and     [eax + SOCKET.options], not (SS_ISCONNECTING + SS_ISDISCONNECTING + SS_ISCONFIRMING)
1877
        or      [eax + SOCKET.options], SS_ISCONNECTED
1885 hidnplayr 1878
 
2402 hidnplayr 1879
        jmp     SOCKET_notify_owner
1885 hidnplayr 1880
 
1881
 
1882
 
1883
 
1884
;-----------------------------------------------------------------
1885
;
1773 hidnplayr 1886
; SOCKET_is_disconnecting
1887
;
1888
;  IN:  eax = socket ptr
1889
;  OUT: /
1890
;
1891
;-----------------------------------------------------------------
1892
 
1893
align 4
1894
SOCKET_is_disconnecting:
1895
 
2891 hidnplayr 1896
        DEBUGF  1,"SOCKET_is_disconnecting: %x\n", eax
1897
 
2402 hidnplayr 1898
        and     [eax + SOCKET.options], not (SS_ISCONNECTING)
1899
        or      [eax + SOCKET.options], SS_ISDISCONNECTING + SS_CANTRCVMORE + SS_CANTSENDMORE
1773 hidnplayr 1900
 
2402 hidnplayr 1901
        jmp     SOCKET_notify_owner
1773 hidnplayr 1902
 
1903
 
1904
 
1905
;-----------------------------------------------------------------
1906
;
1907
; SOCKET_is_disconnected
1908
;
1909
;  IN:  eax = socket ptr
1910
;  OUT: /
1911
;
1912
;-----------------------------------------------------------------
1913
 
1914
align 4
1915
SOCKET_is_disconnected:
1916
 
2891 hidnplayr 1917
        DEBUGF  1,"SOCKET_is_disconnected: %x\n", eax
1918
 
2402 hidnplayr 1919
        and     [eax + SOCKET.options], not (SS_ISCONNECTING + SS_ISCONNECTED + SS_ISDISCONNECTING)
1920
        or      [eax + SOCKET.options], SS_CANTRCVMORE + SS_CANTSENDMORE
1773 hidnplayr 1921
 
2402 hidnplayr 1922
        jmp     SOCKET_notify_owner
1774 hidnplayr 1923
 
1924
 
1925
;-----------------------------------------------------------------
1926
;
1927
; SOCKET_cant_recv_more
1928
;
1929
;  IN:  eax = socket ptr
1930
;  OUT: /
1931
;
1932
;-----------------------------------------------------------------
1933
 
1934
align 4
1935
SOCKET_cant_recv_more:
1936
 
2891 hidnplayr 1937
        DEBUGF  1,"SOCKET_cant_recv_more: %x\n", eax
1938
 
2402 hidnplayr 1939
        or      [eax + SOCKET.options], SS_CANTRCVMORE
1885 hidnplayr 1940
 
2402 hidnplayr 1941
        ret
1831 hidnplayr 1942
 
1943
 
1944
 
1945
;-----------------------------------------------------------------
1946
;
1885 hidnplayr 1947
; SOCKET_cant_send_more
1831 hidnplayr 1948
;
1949
;  IN:  eax = socket ptr
1950
;  OUT: /
1951
;
1952
;-----------------------------------------------------------------
1953
 
1954
align 4
1885 hidnplayr 1955
SOCKET_cant_send_more:
1831 hidnplayr 1956
 
2891 hidnplayr 1957
        DEBUGF  1,"SOCKET_cant_send_more: %x\n", eax
1958
 
2402 hidnplayr 1959
        or      [eax + SOCKET.options], SS_CANTSENDMORE
1831 hidnplayr 1960
 
2402 hidnplayr 1961
        ret