Subversion Repositories Kolibri OS

Rev

Rev 9917 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
3545 hidnplayr 1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2
;;                                                                 ;;
10051 ace_dent 3
;; Copyright (C) KolibriOS team 2004-2024. All rights reserved.    ;;
3545 hidnplayr 4
;; Distributed under terms of the GNU General Public License       ;;
5
;;                                                                 ;;
6
;;  STACK.INC                                                      ;;
7
;;                                                                 ;;
8
;;  TCP/IP stack for KolibriOS                                     ;;
9
;;                                                                 ;;
10
;;    Written by hidnplayr@kolibrios.org                           ;;
11
;;                                                                 ;;
12
;;     Some parts of code are based on the work of:                ;;
13
;;      Mike Hibbett (menuetos network stack)                      ;;
14
;;      Eugen Brasoveanu (solar os network stack and drivers)      ;;
15
;;      mike.dld (kolibrios socket code)                           ;;
16
;;                                                                 ;;
17
;;     TCP part is based on 4.4BSD                                 ;;
18
;;                                                                 ;;
19
;;          GNU GENERAL PUBLIC LICENSE                             ;;
20
;;             Version 2, June 1991                                ;;
21
;;                                                                 ;;
22
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
23
 
24
 
25
uglobal
26
        net_10ms        dd ?
27
        net_tmr_count   dw ?
28
endg
29
 
3556 hidnplayr 30
DEBUG_NETWORK_ERROR     = 1
4388 hidnplayr 31
DEBUG_NETWORK_VERBOSE   = 0
9017 hidnplayr 32
NETWORK_SANITY_CHECKS   = 1
3556 hidnplayr 33
 
3600 hidnplayr 34
NET_DEVICES_MAX         = 16
5528 hidnplayr 35
NET_BUFFERS             = 512
36
NET_BUFFER_SIZE         = 2048
3545 hidnplayr 37
ARP_BLOCK               = 1             ; true or false
38
 
3600 hidnplayr 39
EPHEMERAL_PORT_MIN      = 49152
40
EPHEMERAL_PORT_MAX      = 61000
3545 hidnplayr 41
MIN_EPHEMERAL_PORT_N    = 0x00C0        ; same in Network byte order (FIXME)
42
MAX_EPHEMERAL_PORT_N    = 0x48EE        ; same in Network byte order (FIXME)
43
 
44
; Ethernet protocol numbers
3600 hidnplayr 45
ETHER_PROTO_ARP                 = 0x0608
46
ETHER_PROTO_IPv4                = 0x0008
47
ETHER_PROTO_IPv6                = 0xDD86
48
ETHER_PROTO_PPP_DISCOVERY       = 0x6388
49
ETHER_PROTO_PPP_SESSION         = 0x6488
3545 hidnplayr 50
 
3600 hidnplayr 51
; Internet protocol numbers
52
IP_PROTO_IP             = 0
53
IP_PROTO_ICMP           = 1
54
IP_PROTO_TCP            = 6
55
IP_PROTO_UDP            = 17
5842 hidnplayr 56
IP_PROTO_RAW            = 255
3600 hidnplayr 57
 
5842 hidnplayr 58
; IP options
59
IP_TOS                  = 1
60
IP_TTL                  = 2
61
IP_HDRINCL              = 3
62
 
3545 hidnplayr 63
; PPP protocol numbers
3600 hidnplayr 64
PPP_PROTO_IPv4          = 0x2100
65
PPP_PROTO_IPV6          = 0x5780
66
PPP_PROTO_ETHERNET      = 666           ; FIXME
3545 hidnplayr 67
 
68
;Protocol family
69
AF_UNSPEC               = 0
70
AF_LOCAL                = 1
71
AF_INET4                = 2
72
AF_INET6                = 10
3600 hidnplayr 73
AF_PPP                  = 777           ; FIXME
3545 hidnplayr 74
 
75
; Socket types
76
SOCK_STREAM             = 1
77
SOCK_DGRAM              = 2
78
SOCK_RAW                = 3
79
 
5842 hidnplayr 80
; Socket level
81
SOL_SOCKET              = 0xffff
82
 
3545 hidnplayr 83
; Socket options
84
SO_ACCEPTCON            = 1 shl 0
85
SO_BROADCAST            = 1 shl 1
86
SO_DEBUG                = 1 shl 2
87
SO_DONTROUTE            = 1 shl 3
88
SO_KEEPALIVE            = 1 shl 4
89
SO_OOBINLINE            = 1 shl 5
90
SO_REUSEADDR            = 1 shl 6
91
SO_REUSEPORT            = 1 shl 7
92
SO_USELOOPBACK          = 1 shl 8
93
SO_BINDTODEVICE         = 1 shl 9
6476 hidnplayr 94
SO_LINGER               = 1 shl 10
3545 hidnplayr 95
 
96
SO_NONBLOCK             = 1 shl 31
97
 
98
; Socket flags for user calls
99
MSG_PEEK                = 0x02
100
MSG_DONTWAIT            = 0x40
101
 
102
; Socket States
3600 hidnplayr 103
SS_NOFDREF              = 0x0001        ; no file table ref any more
104
SS_ISCONNECTED          = 0x0002        ; socket connected to a peer
105
SS_ISCONNECTING         = 0x0004        ; in process of connecting to peer
106
SS_ISDISCONNECTING      = 0x0008        ; in process of disconnecting
107
SS_CANTSENDMORE         = 0x0010        ; can't send more data to peer
108
SS_CANTRCVMORE          = 0x0020        ; can't receive more data from peer
109
SS_RCVATMARK            = 0x0040        ; at mark on input
110
SS_ISABORTING           = 0x0080        ; aborting fd references - close()
111
SS_RESTARTSYS           = 0x0100        ; restart blocked system calls
112
SS_ISDISCONNECTED       = 0x0800        ; socket disconnected from peer
3545 hidnplayr 113
 
3674 hidnplayr 114
SS_ASYNC                = 0x1000        ; async i/o notify
115
SS_ISCONFIRMING         = 0x2000        ; deciding to accept connection req
116
SS_MORETOCOME           = 0x4000
3545 hidnplayr 117
 
118
SS_BLOCKED              = 0x8000
119
 
120
 
6413 hidnplayr 121
SOCKET_BUFFER_SIZE      = 4096*8        ; must be 4096*(power of 2) where 'power of 2' is at least 8
3600 hidnplayr 122
MAX_backlog             = 20            ; maximum backlog for stream sockets
3545 hidnplayr 123
 
124
; Error Codes
3674 hidnplayr 125
ENOBUFS                 = 1
4025 hidnplayr 126
EINPROGRESS             = 2
3674 hidnplayr 127
EOPNOTSUPP              = 4
128
EWOULDBLOCK             = 6
129
ENOTCONN                = 9
130
EALREADY                = 10
131
EINVAL                  = 11
132
EMSGSIZE                = 12
133
ENOMEM                  = 18
134
EADDRINUSE              = 20
6476 hidnplayr 135
EADDRNOTAVAIL           = 21
3545 hidnplayr 136
ECONNRESET              = 52
6476 hidnplayr 137
ECONNABORTED            = 53
4025 hidnplayr 138
EISCONN                 = 56
3545 hidnplayr 139
ETIMEDOUT               = 60
6476 hidnplayr 140
ECONNREFUSED            = 61
3545 hidnplayr 141
 
142
; Api protocol numbers
143
API_ETH                 = 0
144
API_IPv4                = 1
145
API_ICMP                = 2
146
API_UDP                 = 3
147
API_TCP                 = 4
148
API_ARP                 = 5
149
API_PPPOE               = 6
150
API_IPv6                = 7
151
 
3600 hidnplayr 152
; Network device types
153
NET_DEVICE_LOOPBACK     = 0
154
NET_DEVICE_ETH          = 1
155
NET_DEVICE_SLIP         = 2
156
 
157
; Network link types (link protocols)
5528 hidnplayr 158
NET_LINK_LOOPBACK       = 0
3600 hidnplayr 159
NET_LINK_MAC            = 1     ; Media access control (ethernet, isdn, ...)
160
NET_LINK_PPP            = 2     ; Point to Point Protocol (PPPoE, ...)
161
NET_LINK_IEEE802.11     = 3     ; IEEE 802.11 (WiFi)
162
 
163
; Hardware acceleration bits
4387 hidnplayr 164
NET_HWACC_TCP_IPv4_IN   = 1 shl 0
165
NET_HWACC_TCP_IPv4_OUT  = 1 shl 1
3545 hidnplayr 166
 
5522 hidnplayr 167
; Network frame types
6011 hidnplayr 168
NET_BUFF_LOOPBACK       = 0
169
NET_BUFF_ETH            = 1
5522 hidnplayr 170
 
3545 hidnplayr 171
struct  NET_DEVICE
172
 
3600 hidnplayr 173
        device_type     dd ?    ; Type field
3545 hidnplayr 174
        mtu             dd ?    ; Maximal Transmission Unit
175
        name            dd ?    ; Ptr to 0 terminated string
176
 
177
        unload          dd ?    ; Ptrs to driver functions
178
        reset           dd ?    ;
179
        transmit        dd ?    ;
180
 
8896 hidnplayr 181
        link_state      dd ?    ; link state (0 = no link)
182
        hwacc           dd ?    ; bitmask stating enabled HW accelerations (offload engines)
183
 
3545 hidnplayr 184
        bytes_tx        dq ?    ; Statistics, updated by the driver
185
        bytes_rx        dq ?    ;
8896 hidnplayr 186
 
3545 hidnplayr 187
        packets_tx      dd ?    ;
8896 hidnplayr 188
        packets_tx_err  dd ?    ; CRC errors, too long or too short frames
189
        packets_tx_drop dd ?    ;
190
        packets_tx_ovr  dd ?    ; FIFO overrun
191
 
3545 hidnplayr 192
        packets_rx      dd ?    ;
8896 hidnplayr 193
        packets_rx_err  dd ?    ; CRC errors, too long or too short frames
194
        packets_rx_drop dd ?    ;
195
        packets_rx_ovr  dd ?    ; FIFO overrun
3545 hidnplayr 196
 
197
ends
198
 
5522 hidnplayr 199
struct  NET_BUFF
3545 hidnplayr 200
 
5522 hidnplayr 201
        NextPtr         dd ?    ; pointer to next frame in list
202
        PrevPtr         dd ?    ; pointer to previous frame in list
203
        device          dd ?    ; ptr to NET_DEVICE structure
204
        type            dd ?    ; encapsulation type: e.g. Ethernet
205
        length          dd ?    ; size of encapsulated data
206
        offset          dd ?    ; offset to actual data (24 bytes for default frame)
207
        data            rb 0
208
 
209
ends
210
 
211
 
3545 hidnplayr 212
; Exactly as it says..
213
macro pseudo_random reg {
214
        add     reg, [esp]
215
        rol     reg, 5
216
        xor     reg, [timer_ticks]
217
;        add     reg, [CPU_FREQ]
218
        imul    reg, 214013
219
        xor     reg, 0xdeadbeef
220
        rol     reg, 9
221
}
222
 
223
; Network to Hardware byte order (dword)
224
macro ntohd reg {
225
 
226
        rol     word reg, 8
227
        rol     dword reg, 16
228
        rol     word reg , 8
229
 
230
}
231
 
232
; Network to Hardware byte order (word)
233
macro ntohw reg {
234
 
235
        rol     word reg, 8
236
 
237
}
238
 
239
 
240
include "queue.inc"
241
 
242
include "loopback.inc"
243
include "ethernet.inc"
244
 
9049 hidnplayr 245
;include "PPPoE.inc"
3545 hidnplayr 246
 
247
include "ARP.inc"
248
include "IPv4.inc"
9049 hidnplayr 249
;include "IPv6.inc"
3545 hidnplayr 250
 
251
include "icmp.inc"
252
include "udp.inc"
253
include "tcp.inc"
254
 
255
include "socket.inc"
256
 
257
 
258
 
3698 hidnplayr 259
uglobal
3545 hidnplayr 260
align 4
261
 
7679 hidnplayr 262
        net_device_count        dd ?
263
        net_device_list         rd NET_DEVICES_MAX
3545 hidnplayr 264
 
9017 hidnplayr 265
        net_buffs_free          rd NET_BUFFERS  ; list of pointers to actual net buffs
266
        .current                dd ?            ; pointer to current element in net_buffs_free list
5528 hidnplayr 267
 
9017 hidnplayr 268
if defined NETWORK_SANITY_CHECKS
269
        net_buffs_low           dd ?            ; actual net buff mem region start
270
        net_buffs_high          dd ?            ; actual net buff mem region stop
271
end if
272
 
3545 hidnplayr 273
endg
274
 
275
 
6011 hidnplayr 276
;-----------------------------------------------------------------;
277
;                                                                 ;
278
; stack_init: Initialize all network variables                    ;
279
;                                                                 ;
280
;  IN:  /                                                         ;
281
;  OUT: /                                                         ;
282
;                                                                 ;
283
;-----------------------------------------------------------------;
3545 hidnplayr 284
align 4
285
stack_init:
286
 
5528 hidnplayr 287
; allocate network buffers
288
        stdcall kernel_alloc, NET_BUFFER_SIZE*NET_BUFFERS
289
        test    eax, eax
290
        jz      .fail
291
 
9017 hidnplayr 292
if defined NETWORK_SANITY_CHECKS
293
        mov     [net_buffs_low], eax
294
end if
295
 
7678 hidnplayr 296
        mov     edi, net_buffs_free
5528 hidnplayr 297
        mov     ecx, NET_BUFFERS
298
        cld
299
  .loop:
300
        stosd
301
        add     eax, NET_BUFFER_SIZE
302
        dec     ecx
303
        jnz     .loop
304
 
9017 hidnplayr 305
if defined NETWORK_SANITY_CHECKS
306
        sub     eax, NET_BUFFER_SIZE
307
        mov     [net_buffs_high], eax
308
end if
309
 
7678 hidnplayr 310
        mov     eax, net_buffs_free
5528 hidnplayr 311
        stosd
312
 
3545 hidnplayr 313
; Init the network drivers list
314
        xor     eax, eax
7679 hidnplayr 315
        mov     edi, net_device_count
5524 hidnplayr 316
        mov     ecx, (NET_DEVICES_MAX + 1)
3711 clevermous 317
        rep stosd
3545 hidnplayr 318
 
6011 hidnplayr 319
        eth_init
3982 hidnplayr 320
 
9049 hidnplayr 321
;        pppoe_init
3545 hidnplayr 322
 
6011 hidnplayr 323
        ipv4_init
324
;        ipv6_init
325
        icmp_init
3545 hidnplayr 326
 
6011 hidnplayr 327
        arp_init
328
        udp_init
329
        tcp_init
3545 hidnplayr 330
 
6011 hidnplayr 331
        socket_init
3545 hidnplayr 332
 
6011 hidnplayr 333
        loop_init
3601 hidnplayr 334
 
3545 hidnplayr 335
        mov     [net_tmr_count], 0
5528 hidnplayr 336
        ret
3545 hidnplayr 337
 
5528 hidnplayr 338
  .fail:
339
        DEBUGF  DEBUG_NETWORK_ERROR, "Stack init failed!\n"
3545 hidnplayr 340
        ret
341
 
342
 
343
 
344
; Wakeup every tick.
345
proc stack_handler_has_work?
346
 
3711 clevermous 347
        mov     eax, [timer_ticks]
348
        cmp     eax, [net_10ms]
3545 hidnplayr 349
 
350
        ret
351
endp
352
 
353
 
6011 hidnplayr 354
;-----------------------------------------------------------------;
355
;                                                                 ;
356
; stack_handler: Network handlers called from os_loop.            ;
357
;                                                                 ;
358
;  IN:  /                                                         ;
359
;  OUT: /                                                         ;
360
;                                                                 ;
361
;-----------------------------------------------------------------;
3545 hidnplayr 362
align 4
363
stack_handler:
364
 
365
        ; Test for 10ms tick
366
        mov     eax, [timer_ticks]
367
        cmp     eax, [net_10ms]
368
        je      .exit
369
        mov     [net_10ms], eax
370
 
7679 hidnplayr 371
        cmp     [net_device_count], 0
3545 hidnplayr 372
        je      .exit
373
 
374
        test    [net_10ms], 0x0f        ; 160ms
375
        jnz     .exit
376
 
6011 hidnplayr 377
        tcp_timer_160ms
3545 hidnplayr 378
 
379
        test    [net_10ms], 0x3f        ; 640ms
380
        jnz     .exit
381
 
6011 hidnplayr 382
        arp_decrease_entry_ttls
383
        ipv4_decrease_fragment_ttls
3545 hidnplayr 384
 
5013 hidnplayr 385
        xor     edx, edx
386
        mov     eax, [TCP_timer1_event]
387
        mov     ebx, [eax + EVENT.id]
388
        xor     esi, esi
389
        call    raise_event
390
 
3545 hidnplayr 391
  .exit:
392
        ret
393
 
394
 
3861 hidnplayr 395
align 4
6011 hidnplayr 396
proc net_buff_alloc stdcall, buffersize
397
 
5528 hidnplayr 398
        cmp     [buffersize], NET_BUFFER_SIZE
399
        ja      .too_large
5522 hidnplayr 400
 
5528 hidnplayr 401
        spin_lock_irqsave
5522 hidnplayr 402
 
7678 hidnplayr 403
        mov     eax, [net_buffs_free.current]
404
        cmp     eax, net_buffs_free+NET_BUFFERS*4
5528 hidnplayr 405
        jae     .out_of_mem
406
        mov     eax, [eax]
7678 hidnplayr 407
        add     [net_buffs_free.current], 4
5528 hidnplayr 408
 
409
        spin_unlock_irqrestore
410
 
9017 hidnplayr 411
if defined NETWORK_SANITY_CHECKS
412
        cmp     eax, [net_buffs_low]
413
        cmp     eax, [net_buffs_low]
414
        jb      .assert_mbuff
415
        cmp     eax, [net_buffs_high]
416
        ja      .assert_mbuff
417
        test    eax, 0x7ff
418
        jnz     .assert_mbuff
419
end if
420
 
6011 hidnplayr 421
        DEBUGF  DEBUG_NETWORK_VERBOSE, "net_buff_alloc: 0x%x\n", eax
5528 hidnplayr 422
        ret
423
 
424
  .out_of_mem:
425
        spin_unlock_irqrestore
426
 
427
        xor     eax, eax
6011 hidnplayr 428
        DEBUGF  DEBUG_NETWORK_ERROR, "net_buff_alloc: out of mem!\n"
5528 hidnplayr 429
        ret
430
 
431
  .too_large:
432
        xor     eax, eax
6011 hidnplayr 433
        DEBUGF  DEBUG_NETWORK_ERROR, "net_buff_alloc: too large!\n"
5528 hidnplayr 434
        ret
9017 hidnplayr 435
 
436
if defined NETWORK_SANITY_CHECKS
437
  .assert_mbuff:
438
        DEBUGF  DEBUG_NETWORK_ERROR, "net_buff_alloc: invalid buffer 0x%x\n", eax
439
        DEBUGF  DEBUG_NETWORK_ERROR, "net_buff_alloc: caller=0x%x\n", [esp+4]
440
        xor     eax, eax
441
        ret
442
end if
443
 
5528 hidnplayr 444
endp
445
 
446
 
5522 hidnplayr 447
align 4
6011 hidnplayr 448
proc net_buff_free stdcall, buffer
3545 hidnplayr 449
 
6011 hidnplayr 450
        DEBUGF  DEBUG_NETWORK_VERBOSE, "net_buff_free: 0x%x\n", [buffer]
3861 hidnplayr 451
 
9017 hidnplayr 452
if defined NETWORK_SANITY_CHECKS
453
        mov     eax, [buffer]
454
        cmp     eax, [net_buffs_low]
455
        jb      .assert_mbuff
456
        cmp     eax, [net_buffs_high]
457
        ja      .assert_mbuff
458
        test    eax, 0x7ff
459
        jnz     .assert_mbuff
460
end if
461
 
5528 hidnplayr 462
        spin_lock_irqsave
463
 
8896 hidnplayr 464
        sub     [net_buffs_free.current], 4             ; move pointer backwards
465
        mov     eax, [net_buffs_free.current]           ; place free'd buffer pointer on the list
5528 hidnplayr 466
        push    [buffer]
467
        pop     dword[eax]
468
 
469
        spin_unlock_irqrestore
470
 
471
        ret
9017 hidnplayr 472
 
473
if defined NETWORK_SANITY_CHECKS
474
  .assert_mbuff:
475
        DEBUGF  DEBUG_NETWORK_ERROR, "net_buff_free: invalid buffer 0x%x\n", eax
476
        DEBUGF  DEBUG_NETWORK_ERROR, "net_buff_free: caller=0x%x\n", [esp+4]
477
        xor     eax, eax
478
        ret
479
end if
480
 
5528 hidnplayr 481
endp
482
 
483
 
3545 hidnplayr 484
align 4
6011 hidnplayr 485
net_link_changed:
3545 hidnplayr 486
 
6011 hidnplayr 487
        DEBUGF  DEBUG_NETWORK_VERBOSE, "net_link_changed device=0x%x status=0x%x\n", ebx, [ebx + NET_DEVICE.link_state]
3545 hidnplayr 488
 
489
align 4
6011 hidnplayr 490
net_send_event:
3545 hidnplayr 491
 
6011 hidnplayr 492
        DEBUGF  DEBUG_NETWORK_VERBOSE, "net_send_event\n"
3545 hidnplayr 493
 
494
; Send event to all applications
495
        push    edi ecx
496
        mov     edi, SLOT_BASE
8866 rgimad 497
        mov     ecx, [thread_count]
3545 hidnplayr 498
  .loop:
8867 rgimad 499
        add     edi, sizeof.APPDATA
500
        or      [edi + APPDATA.occurred_events], EVENT_NETWORK2
3545 hidnplayr 501
        loop    .loop
502
        pop     ecx edi
503
 
504
        ret
505
 
506
 
507
 
6011 hidnplayr 508
;-----------------------------------------------------------------;
509
;                                                                 ;
510
; net_add_device: Called by network driver to register interface. ;
511
;                                                                 ;
512
;  IN:  ebx = ptr to device structure                             ;
513
;                                                                 ;
514
;  OUT: eax = device num on success                               ;
515
;       eax = -1 on error                                         ;
516
;                                                                 ;
517
;-----------------------------------------------------------------;
3545 hidnplayr 518
align 4
6011 hidnplayr 519
net_add_device:
3545 hidnplayr 520
 
6011 hidnplayr 521
        DEBUGF  DEBUG_NETWORK_VERBOSE, "net_add_device: %x\n", ebx   ;;; TODO: use mutex to lock net device list
3545 hidnplayr 522
 
7679 hidnplayr 523
        cmp     [net_device_count], NET_DEVICES_MAX
3545 hidnplayr 524
        jae     .error
525
 
526
;----------------------------------
527
; Check if device is already listed
528
        mov     eax, ebx
3600 hidnplayr 529
        mov     ecx, NET_DEVICES_MAX    ; We need to check whole list because a device may be removed without re-organizing list
7679 hidnplayr 530
        mov     edi, net_device_list
3545 hidnplayr 531
 
3711 clevermous 532
        repne scasd                     ; See if device is already in the list
3545 hidnplayr 533
        jz      .error
534
 
535
;----------------------------
536
; Find empty slot in the list
537
        xor     eax, eax
3600 hidnplayr 538
        mov     ecx, NET_DEVICES_MAX
7679 hidnplayr 539
        mov     edi, net_device_list
3545 hidnplayr 540
 
3711 clevermous 541
        repne scasd
3545 hidnplayr 542
        jnz     .error
543
 
544
        sub     edi, 4
545
 
546
;-----------------------------
547
; Add device to the found slot
548
        mov     [edi], ebx              ; add device to list
549
 
550
        mov     eax, edi                ; Calculate device number in eax
7679 hidnplayr 551
        sub     eax, net_device_list
3545 hidnplayr 552
        shr     eax, 2
553
 
7679 hidnplayr 554
        inc     [net_device_count]      ; Indicate that one more network device is up and running
3545 hidnplayr 555
 
6011 hidnplayr 556
        call    net_send_event
3545 hidnplayr 557
 
3556 hidnplayr 558
        DEBUGF  DEBUG_NETWORK_VERBOSE, "Device number: %u\n", eax
3545 hidnplayr 559
        ret
560
 
561
  .error:
562
        or      eax, -1
3556 hidnplayr 563
        DEBUGF  DEBUG_NETWORK_ERROR, "Adding network device failed\n"
3545 hidnplayr 564
        ret
565
 
566
 
567
 
6011 hidnplayr 568
;-----------------------------------------------------------------;
569
;                                                                 ;
570
; net_remove_device: Called by network driver to unregister dev.  ;
571
;                                                                 ;
572
;  IN:  ebx = ptr to device                                       ;
573
;                                                                 ;
574
;  OUT: eax: -1 on error                                          ;
575
;                                                                 ;
576
;-----------------------------------------------------------------;
3545 hidnplayr 577
align 4
6011 hidnplayr 578
net_remove_device:
3545 hidnplayr 579
 
7679 hidnplayr 580
        cmp     [net_device_count], 0
3545 hidnplayr 581
        je      .error
582
 
583
;----------------------------
584
; Find the driver in the list
585
 
586
        mov     eax, ebx
3600 hidnplayr 587
        mov     ecx, NET_DEVICES_MAX
7679 hidnplayr 588
        mov     edi, net_device_list
3545 hidnplayr 589
 
3711 clevermous 590
        repne scasd
3545 hidnplayr 591
        jnz     .error
592
 
593
;------------------------
594
; Remove it from the list
595
 
596
        xor     eax, eax
597
        mov     dword [edi-4], eax
7679 hidnplayr 598
        dec     [net_device_count]
3545 hidnplayr 599
 
6011 hidnplayr 600
        call    net_send_event
3545 hidnplayr 601
 
3601 hidnplayr 602
        xor     eax, eax
3545 hidnplayr 603
        ret
604
 
605
  .error:
606
        or      eax, -1
607
        ret
608
 
609
 
610
 
6011 hidnplayr 611
;-----------------------------------------------------------------;
612
;                                                                 ;
613
; net_ptr_to_num                                                  ;
614
;                                                                 ;
615
;  IN:  ebx = ptr to device struct                                ;
616
;                                                                 ;
617
;  OUT: edi = device number                                       ;
618
;       edi = -1 on error                                         ;
619
;                                                                 ;
620
;-----------------------------------------------------------------;
3545 hidnplayr 621
align 4
6011 hidnplayr 622
net_ptr_to_num:
3643 hidnplayr 623
 
6011 hidnplayr 624
        call    net_ptr_to_num4
3643 hidnplayr 625
        ror     edi, 2          ; If -1, stay -1
626
                                ; valid device numbers have last two bits 0, so do just shr
627
 
628
        ret
629
 
630
align 4
6011 hidnplayr 631
net_ptr_to_num4:                ; Todo, place number in device structure so we only need to verify?
3643 hidnplayr 632
 
5522 hidnplayr 633
        test    ebx, ebx
634
        jz      .fail
635
 
3545 hidnplayr 636
        push    ecx
3600 hidnplayr 637
        mov     ecx, NET_DEVICES_MAX
7679 hidnplayr 638
        mov     edi, net_device_list
3545 hidnplayr 639
  .loop:
640
        cmp     ebx, [edi]
3643 hidnplayr 641
        je      .found
3545 hidnplayr 642
        add     edi, 4
643
        dec     ecx
644
        jnz     .loop
645
 
5522 hidnplayr 646
        pop     ecx
647
  .fail:
3545 hidnplayr 648
        or      edi, -1
649
        ret
650
 
651
  .found:
7679 hidnplayr 652
        sub     edi, net_device_list
3545 hidnplayr 653
        pop     ecx
654
        ret
655
 
6011 hidnplayr 656
;-----------------------------------------------------------------;
657
;                                                                 ;
658
; checksum_1: Calculate semi-checksum for network packets.        ;
659
;                                                                 ;
660
;  IN:  edx = start offset for semi-checksum                      ;
661
;       esi = pointer to data                                     ;
662
;       ecx = data size                                           ;
663
;                                                                 ;
664
;  OUT: edx = semi-checksum                                       ;
665
;                                                                 ;
666
;-----------------------------------------------------------------;
3545 hidnplayr 667
align 4
668
checksum_1:
669
 
670
        shr     ecx, 1
671
        pushf
672
        jz      .no_2
673
 
674
        shr     ecx, 1
675
        pushf
676
        jz      .no_4
677
 
678
        shr     ecx, 1
679
        pushf
680
        jz      .no_8
681
 
682
  .loop:
683
        add     dl, [esi+1]
684
        adc     dh, [esi+0]
685
 
686
        adc     dl, [esi+3]
687
        adc     dh, [esi+2]
688
 
689
        adc     dl, [esi+5]
690
        adc     dh, [esi+4]
691
 
692
        adc     dl, [esi+7]
693
        adc     dh, [esi+6]
694
 
695
        adc     edx, 0
696
        add     esi, 8
697
 
698
        dec     ecx
699
        jnz     .loop
700
 
701
        adc     edx, 0
702
 
703
  .no_8:
704
        popf
705
        jnc     .no_4
706
 
707
        add     dl, [esi+1]
708
        adc     dh, [esi+0]
709
 
710
        adc     dl, [esi+3]
711
        adc     dh, [esi+2]
712
 
713
        adc     edx, 0
714
        add     esi, 4
715
 
716
  .no_4:
717
        popf
718
        jnc     .no_2
719
 
720
        add     dl, [esi+1]
721
        adc     dh, [esi+0]
722
 
723
        adc     edx, 0
724
        inc     esi
725
        inc     esi
726
 
727
  .no_2:
728
        popf
729
        jnc     .end
730
 
731
        add     dh, [esi+0]
732
        adc     edx, 0
733
  .end:
734
        ret
735
 
6011 hidnplayr 736
;-----------------------------------------------------------------;
737
;                                                                 ;
738
; checksum_2: Calculate the final ip/tcp/udp checksum.            ;
739
;                                                                 ;
740
;   IN: edx = semi-checksum                                       ;
741
;                                                                 ;
742
;  OUT: dx = checksum (in INET byte order)                        ;
743
;                                                                 ;
744
;-----------------------------------------------------------------;
3545 hidnplayr 745
align 4
746
checksum_2:
747
 
748
        mov     ecx, edx
749
        shr     ecx, 16
750
        and     edx, 0xffff
751
        add     edx, ecx
752
 
753
        mov     ecx, edx
754
        shr     ecx, 16
755
        add     dx, cx
756
        test    dx, dx          ; it seems that ZF is not set when CF is set :(
757
        not     dx
758
        jnz     .not_zero
759
        dec     dx
760
  .not_zero:
761
        xchg    dl, dh
762
 
3556 hidnplayr 763
        DEBUGF  DEBUG_NETWORK_VERBOSE, "Checksum: %x\n", dx
3545 hidnplayr 764
 
765
        ret
766
 
767
 
768
 
6011 hidnplayr 769
;-----------------------------------------------------------------;
770
;                                                                 ;
771
;  System function 74: Low level access to network devices.       ;
772
;                                                                 ;
773
;-----------------------------------------------------------------;
3545 hidnplayr 774
align 4
3601 hidnplayr 775
sys_network:
3545 hidnplayr 776
 
3879 hidnplayr 777
        cmp     bl, 255
3545 hidnplayr 778
        jne     @f
779
 
7679 hidnplayr 780
        mov     eax, [net_device_count]
9917 Doczom 781
        mov     [esp + SYSCALL_STACK.eax], eax
3601 hidnplayr 782
        ret
3545 hidnplayr 783
 
784
   @@:
7679 hidnplayr 785
        cmp     bh, NET_DEVICES_MAX                     ; Check if device number exists
3545 hidnplayr 786
        jae     .doesnt_exist
787
 
788
        mov     esi, ebx
789
        and     esi, 0x0000ff00
790
        shr     esi, 6
791
 
7679 hidnplayr 792
        cmp     dword[esi + net_device_list], 0         ; check if device is running
3545 hidnplayr 793
        je      .doesnt_exist
794
 
7679 hidnplayr 795
        mov     eax, [esi + net_device_list]
3545 hidnplayr 796
 
797
        and     ebx, 0x000000ff
798
        cmp     ebx, .number
799
        ja      .doesnt_exist
800
        jmp     dword [.table + 4*ebx]
801
 
802
  .table:
9017 hidnplayr 803
        dd      .get_type               ;  0
804
        dd      .get_dev_name           ;  1
805
        dd      .reset                  ;  2
806
        dd      .stop                   ;  3
807
        dd      .get_ptr                ;  4
808
        dd      .get_drv_name           ;  5
3601 hidnplayr 809
 
9017 hidnplayr 810
        dd      .packets_tx             ;  6
811
        dd      .packets_rx             ;  7
812
        dd      .bytes_tx               ;  8
813
        dd      .bytes_rx               ;  9
3601 hidnplayr 814
        dd      .state                  ; 10
9017 hidnplayr 815
        dd      .packets_tx_err         ; 11
816
        dd      .packets_tx_drop        ; 12
817
        dd      .packets_tx_ovr         ; 13
818
        dd      .packets_rx_err         ; 14
819
        dd      .packets_rx_drop        ; 15
820
        dd      .packets_rx_ovr         ; 16
821
 
3545 hidnplayr 822
  .number = ($ - .table) / 4 - 1
823
 
3601 hidnplayr 824
  .get_type:
3600 hidnplayr 825
        mov     eax, [eax + NET_DEVICE.device_type]
9917 Doczom 826
        mov     [esp + SYSCALL_STACK.eax], eax
3601 hidnplayr 827
        ret
3545 hidnplayr 828
 
3601 hidnplayr 829
  .get_dev_name:
8700 Coldy 830
        stdcall is_region_userspace, ecx, 64
9045 dunkaist 831
        jnz     .bad_buffer
9049 hidnplayr 832
        mov     esi, [eax + NET_DEVICE.name]
3545 hidnplayr 833
        mov     edi, ecx
834
 
835
        mov     ecx, 64/4 ; max length
3711 clevermous 836
        rep movsd
3545 hidnplayr 837
 
838
        xor     eax, eax
9917 Doczom 839
        mov     [esp + SYSCALL_STACK.eax], eax
3601 hidnplayr 840
        ret
3545 hidnplayr 841
 
3601 hidnplayr 842
  .reset:
3545 hidnplayr 843
        call    [eax + NET_DEVICE.reset]
9917 Doczom 844
        mov     [esp + SYSCALL_STACK.eax], eax
3601 hidnplayr 845
        ret
3545 hidnplayr 846
 
3601 hidnplayr 847
  .stop:
3545 hidnplayr 848
        call    [eax + NET_DEVICE.unload]
9917 Doczom 849
        mov     [esp + SYSCALL_STACK.eax], eax
3601 hidnplayr 850
        ret
3545 hidnplayr 851
 
852
 
3601 hidnplayr 853
  .get_ptr:
9917 Doczom 854
        mov     [esp + SYSCALL_STACK.eax], eax
3601 hidnplayr 855
        ret
3545 hidnplayr 856
 
857
 
3601 hidnplayr 858
  .get_drv_name:
859
        xor     eax, eax
9917 Doczom 860
        mov     [esp + SYSCALL_STACK.eax], eax
3601 hidnplayr 861
        ret
3545 hidnplayr 862
 
3601 hidnplayr 863
  .packets_tx:
864
        mov     eax, [eax + NET_DEVICE.packets_tx]
9917 Doczom 865
        mov     [esp + SYSCALL_STACK.eax], eax
3601 hidnplayr 866
        ret
3545 hidnplayr 867
 
3601 hidnplayr 868
  .packets_rx:
869
        mov     eax, [eax + NET_DEVICE.packets_rx]
9917 Doczom 870
        mov     [esp + SYSCALL_STACK.eax], eax
3601 hidnplayr 871
        ret
3545 hidnplayr 872
 
3601 hidnplayr 873
  .bytes_tx:
6011 hidnplayr 874
        mov     ebx, dword[eax + NET_DEVICE.bytes_tx + 4]
9917 Doczom 875
        mov     [esp + SYSCALL_STACK.ebx], ebx
6011 hidnplayr 876
        mov     eax, dword[eax + NET_DEVICE.bytes_tx]
9917 Doczom 877
        mov     [esp + SYSCALL_STACK.eax], eax
3601 hidnplayr 878
        ret
3545 hidnplayr 879
 
3601 hidnplayr 880
  .bytes_rx:
6011 hidnplayr 881
        mov     ebx, dword[eax + NET_DEVICE.bytes_rx + 4]
9917 Doczom 882
        mov     [esp + SYSCALL_STACK.ebx], ebx
6011 hidnplayr 883
        mov     eax, dword[eax + NET_DEVICE.bytes_rx]
9917 Doczom 884
        mov     [esp + SYSCALL_STACK.eax], eax
3601 hidnplayr 885
        ret
3545 hidnplayr 886
 
9017 hidnplayr 887
  .packets_tx_err:
888
        mov     eax, [eax + NET_DEVICE.packets_tx_err]
9917 Doczom 889
        mov     [esp + SYSCALL_STACK.eax], eax
9017 hidnplayr 890
        ret
891
 
892
  .packets_tx_drop:
893
        mov     eax, [eax + NET_DEVICE.packets_tx_drop]
9917 Doczom 894
        mov     [esp + SYSCALL_STACK.eax], eax
9017 hidnplayr 895
        ret
896
 
897
  .packets_tx_ovr:
898
        mov     eax, [eax + NET_DEVICE.packets_tx_ovr]
9917 Doczom 899
        mov     [esp + SYSCALL_STACK.eax], eax
9017 hidnplayr 900
        ret
901
 
902
  .packets_rx_err:
903
        mov     eax, [eax + NET_DEVICE.packets_rx_err]
9917 Doczom 904
        mov     [esp + SYSCALL_STACK.eax], eax
9017 hidnplayr 905
        ret
906
 
907
  .packets_rx_drop:
908
        mov     eax, [eax + NET_DEVICE.packets_rx_drop]
9917 Doczom 909
        mov     [esp + SYSCALL_STACK.eax], eax
9017 hidnplayr 910
        ret
911
 
912
  .packets_rx_ovr:
913
        mov     eax, [eax + NET_DEVICE.packets_rx_ovr]
9917 Doczom 914
        mov     [esp + SYSCALL_STACK.eax], eax
9017 hidnplayr 915
        ret
916
 
3601 hidnplayr 917
  .state:
918
        mov     eax, [eax + NET_DEVICE.link_state]
9917 Doczom 919
        mov     [esp + SYSCALL_STACK.eax], eax
3545 hidnplayr 920
        ret
921
 
922
 
3601 hidnplayr 923
  .doesnt_exist:
8700 Coldy 924
  .bad_buffer: ; Sanity check failed, exit
9917 Doczom 925
        mov     dword[esp + SYSCALL_STACK.eax], -1
3601 hidnplayr 926
        ret
927
 
928
 
929
 
6011 hidnplayr 930
;-----------------------------------------------------------------;
931
;                                                                 ;
932
;  System function 76: Low level access to protocol handlers.     ;
933
;                                                                 ;
934
;-----------------------------------------------------------------;
3545 hidnplayr 935
align 4
936
sys_protocols:
3600 hidnplayr 937
        cmp     bh, NET_DEVICES_MAX             ; Check if device number exists
3545 hidnplayr 938
        jae     .doesnt_exist
939
 
7963 hidnplayr 940
        mov     eax, ebx
941
        and     eax, 0x0000ff00
942
        shr     eax, 6                          ; now we have the device num * 4 in eax
943
        cmp     [eax + net_device_list], 0      ; check if device is running
3545 hidnplayr 944
        je      .doesnt_exist
945
 
946
        push    .return                         ; return address (we will be using jumps instead of calls)
947
 
948
        mov     eax, ebx                        ; set ax to protocol number
949
        shr     eax, 16                         ;
950
 
951
        cmp     ax, API_ETH
6011 hidnplayr 952
        je      eth_api
3545 hidnplayr 953
 
954
        cmp     ax, API_IPv4
6011 hidnplayr 955
        je      ipv4_api
3545 hidnplayr 956
 
957
        cmp     ax, API_ICMP
6011 hidnplayr 958
        je      icmp_api
3545 hidnplayr 959
 
960
        cmp     ax, API_UDP
6011 hidnplayr 961
        je      udp_api
3545 hidnplayr 962
 
963
        cmp     ax, API_TCP
6011 hidnplayr 964
        je      tcp_api
3545 hidnplayr 965
 
966
        cmp     ax, API_ARP
6011 hidnplayr 967
        je      arp_api
3545 hidnplayr 968
 
9049 hidnplayr 969
;        cmp     ax, API_PPPOE
970
;        je      pppoe_api
3545 hidnplayr 971
 
9049 hidnplayr 972
;        cmp     ax, API_IPv6
973
;        je      ipv6_api
3545 hidnplayr 974
 
975
        add     esp, 4                           ; if we reached here, no function was called, so we need to balance stack
976
 
977
  .doesnt_exist:
978
        mov     eax, -1
979
 
980
  .return:
9917 Doczom 981
        mov     [esp + SYSCALL_STACK.eax], eax   ; return eax value to the program
3545 hidnplayr 982
        ret