Subversion Repositories Kolibri OS

Rev

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