Subversion Repositories Kolibri OS

Rev

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

Rev Author Line No. Line
3545 hidnplayr 1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2
;;                                                                 ;;
8866 rgimad 3
;; Copyright (C) KolibriOS team 2004-2021. 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
 
4850 mario79 24
$Revision: 8896 $
3545 hidnplayr 25
 
26
uglobal
27
        net_10ms        dd ?
28
        net_tmr_count   dw ?
29
endg
30
 
3556 hidnplayr 31
DEBUG_NETWORK_ERROR     = 1
4388 hidnplayr 32
DEBUG_NETWORK_VERBOSE   = 0
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
 
245
include "PPPoE.inc"
246
 
247
include "ARP.inc"
248
include "IPv4.inc"
249
include "IPv6.inc"
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
 
7679 hidnplayr 265
        net_buffs_free          rd NET_BUFFERS
266
        .current                dd ?
5528 hidnplayr 267
 
3545 hidnplayr 268
endg
269
 
270
 
6011 hidnplayr 271
;-----------------------------------------------------------------;
272
;                                                                 ;
273
; stack_init: Initialize all network variables                    ;
274
;                                                                 ;
275
;  IN:  /                                                         ;
276
;  OUT: /                                                         ;
277
;                                                                 ;
278
;-----------------------------------------------------------------;
3545 hidnplayr 279
align 4
280
stack_init:
281
 
5528 hidnplayr 282
; allocate network buffers
283
        stdcall kernel_alloc, NET_BUFFER_SIZE*NET_BUFFERS
284
        test    eax, eax
285
        jz      .fail
286
 
7678 hidnplayr 287
        mov     edi, net_buffs_free
5528 hidnplayr 288
        mov     ecx, NET_BUFFERS
289
        cld
290
  .loop:
291
        stosd
292
        add     eax, NET_BUFFER_SIZE
293
        dec     ecx
294
        jnz     .loop
295
 
7678 hidnplayr 296
        mov     eax, net_buffs_free
5528 hidnplayr 297
        stosd
298
 
3545 hidnplayr 299
; Init the network drivers list
300
        xor     eax, eax
7679 hidnplayr 301
        mov     edi, net_device_count
5524 hidnplayr 302
        mov     ecx, (NET_DEVICES_MAX + 1)
3711 clevermous 303
        rep stosd
3545 hidnplayr 304
 
6011 hidnplayr 305
        eth_init
3982 hidnplayr 306
 
6011 hidnplayr 307
        pppoe_init
3545 hidnplayr 308
 
6011 hidnplayr 309
        ipv4_init
310
;        ipv6_init
311
        icmp_init
3545 hidnplayr 312
 
6011 hidnplayr 313
        arp_init
314
        udp_init
315
        tcp_init
3545 hidnplayr 316
 
6011 hidnplayr 317
        socket_init
3545 hidnplayr 318
 
6011 hidnplayr 319
        loop_init
3601 hidnplayr 320
 
3545 hidnplayr 321
        mov     [net_tmr_count], 0
5528 hidnplayr 322
        ret
3545 hidnplayr 323
 
5528 hidnplayr 324
  .fail:
325
        DEBUGF  DEBUG_NETWORK_ERROR, "Stack init failed!\n"
3545 hidnplayr 326
        ret
327
 
328
 
329
 
330
; Wakeup every tick.
331
proc stack_handler_has_work?
332
 
3711 clevermous 333
        mov     eax, [timer_ticks]
334
        cmp     eax, [net_10ms]
3545 hidnplayr 335
 
336
        ret
337
endp
338
 
339
 
6011 hidnplayr 340
;-----------------------------------------------------------------;
341
;                                                                 ;
342
; stack_handler: Network handlers called from os_loop.            ;
343
;                                                                 ;
344
;  IN:  /                                                         ;
345
;  OUT: /                                                         ;
346
;                                                                 ;
347
;-----------------------------------------------------------------;
3545 hidnplayr 348
align 4
349
stack_handler:
350
 
351
        ; Test for 10ms tick
352
        mov     eax, [timer_ticks]
353
        cmp     eax, [net_10ms]
354
        je      .exit
355
        mov     [net_10ms], eax
356
 
7679 hidnplayr 357
        cmp     [net_device_count], 0
3545 hidnplayr 358
        je      .exit
359
 
360
        test    [net_10ms], 0x0f        ; 160ms
361
        jnz     .exit
362
 
6011 hidnplayr 363
        tcp_timer_160ms
3545 hidnplayr 364
 
365
        test    [net_10ms], 0x3f        ; 640ms
366
        jnz     .exit
367
 
6011 hidnplayr 368
        arp_decrease_entry_ttls
369
        ipv4_decrease_fragment_ttls
3545 hidnplayr 370
 
5013 hidnplayr 371
        xor     edx, edx
372
        mov     eax, [TCP_timer1_event]
373
        mov     ebx, [eax + EVENT.id]
374
        xor     esi, esi
375
        call    raise_event
376
 
3545 hidnplayr 377
  .exit:
378
        ret
379
 
380
 
3861 hidnplayr 381
align 4
6011 hidnplayr 382
proc net_buff_alloc stdcall, buffersize
383
 
5528 hidnplayr 384
        cmp     [buffersize], NET_BUFFER_SIZE
385
        ja      .too_large
5522 hidnplayr 386
 
5528 hidnplayr 387
        spin_lock_irqsave
5522 hidnplayr 388
 
7678 hidnplayr 389
        mov     eax, [net_buffs_free.current]
390
        cmp     eax, net_buffs_free+NET_BUFFERS*4
5528 hidnplayr 391
        jae     .out_of_mem
392
        mov     eax, [eax]
7678 hidnplayr 393
        add     [net_buffs_free.current], 4
5528 hidnplayr 394
 
395
        spin_unlock_irqrestore
396
 
6011 hidnplayr 397
        DEBUGF  DEBUG_NETWORK_VERBOSE, "net_buff_alloc: 0x%x\n", eax
5528 hidnplayr 398
        ret
399
 
400
  .out_of_mem:
401
        spin_unlock_irqrestore
402
 
403
        xor     eax, eax
6011 hidnplayr 404
        DEBUGF  DEBUG_NETWORK_ERROR, "net_buff_alloc: out of mem!\n"
5528 hidnplayr 405
        ret
406
 
407
  .too_large:
408
        xor     eax, eax
6011 hidnplayr 409
        DEBUGF  DEBUG_NETWORK_ERROR, "net_buff_alloc: too large!\n"
5528 hidnplayr 410
        ret
411
endp
412
 
413
 
5522 hidnplayr 414
align 4
6011 hidnplayr 415
proc net_buff_free stdcall, buffer
3545 hidnplayr 416
 
6011 hidnplayr 417
        DEBUGF  DEBUG_NETWORK_VERBOSE, "net_buff_free: 0x%x\n", [buffer]
3861 hidnplayr 418
 
5528 hidnplayr 419
        spin_lock_irqsave
420
 
8896 hidnplayr 421
        sub     [net_buffs_free.current], 4             ; move pointer backwards
422
        mov     eax, [net_buffs_free.current]           ; place free'd buffer pointer on the list
5528 hidnplayr 423
        push    [buffer]
424
        pop     dword[eax]
425
 
426
        spin_unlock_irqrestore
427
 
428
        ret
429
endp
430
 
431
 
3545 hidnplayr 432
align 4
6011 hidnplayr 433
net_link_changed:
3545 hidnplayr 434
 
6011 hidnplayr 435
        DEBUGF  DEBUG_NETWORK_VERBOSE, "net_link_changed device=0x%x status=0x%x\n", ebx, [ebx + NET_DEVICE.link_state]
3545 hidnplayr 436
 
437
align 4
6011 hidnplayr 438
net_send_event:
3545 hidnplayr 439
 
6011 hidnplayr 440
        DEBUGF  DEBUG_NETWORK_VERBOSE, "net_send_event\n"
3545 hidnplayr 441
 
442
; Send event to all applications
443
        push    edi ecx
444
        mov     edi, SLOT_BASE
8866 rgimad 445
        mov     ecx, [thread_count]
3545 hidnplayr 446
  .loop:
8867 rgimad 447
        add     edi, sizeof.APPDATA
448
        or      [edi + APPDATA.occurred_events], EVENT_NETWORK2
3545 hidnplayr 449
        loop    .loop
450
        pop     ecx edi
451
 
452
        ret
453
 
454
 
455
 
6011 hidnplayr 456
;-----------------------------------------------------------------;
457
;                                                                 ;
458
; net_add_device: Called by network driver to register interface. ;
459
;                                                                 ;
460
;  IN:  ebx = ptr to device structure                             ;
461
;                                                                 ;
462
;  OUT: eax = device num on success                               ;
463
;       eax = -1 on error                                         ;
464
;                                                                 ;
465
;-----------------------------------------------------------------;
3545 hidnplayr 466
align 4
6011 hidnplayr 467
net_add_device:
3545 hidnplayr 468
 
6011 hidnplayr 469
        DEBUGF  DEBUG_NETWORK_VERBOSE, "net_add_device: %x\n", ebx   ;;; TODO: use mutex to lock net device list
3545 hidnplayr 470
 
7679 hidnplayr 471
        cmp     [net_device_count], NET_DEVICES_MAX
3545 hidnplayr 472
        jae     .error
473
 
474
;----------------------------------
475
; Check if device is already listed
476
        mov     eax, ebx
3600 hidnplayr 477
        mov     ecx, NET_DEVICES_MAX    ; We need to check whole list because a device may be removed without re-organizing list
7679 hidnplayr 478
        mov     edi, net_device_list
3545 hidnplayr 479
 
3711 clevermous 480
        repne scasd                     ; See if device is already in the list
3545 hidnplayr 481
        jz      .error
482
 
483
;----------------------------
484
; Find empty slot in the list
485
        xor     eax, eax
3600 hidnplayr 486
        mov     ecx, NET_DEVICES_MAX
7679 hidnplayr 487
        mov     edi, net_device_list
3545 hidnplayr 488
 
3711 clevermous 489
        repne scasd
3545 hidnplayr 490
        jnz     .error
491
 
492
        sub     edi, 4
493
 
494
;-----------------------------
495
; Add device to the found slot
496
        mov     [edi], ebx              ; add device to list
497
 
498
        mov     eax, edi                ; Calculate device number in eax
7679 hidnplayr 499
        sub     eax, net_device_list
3545 hidnplayr 500
        shr     eax, 2
501
 
7679 hidnplayr 502
        inc     [net_device_count]      ; Indicate that one more network device is up and running
3545 hidnplayr 503
 
6011 hidnplayr 504
        call    net_send_event
3545 hidnplayr 505
 
3556 hidnplayr 506
        DEBUGF  DEBUG_NETWORK_VERBOSE, "Device number: %u\n", eax
3545 hidnplayr 507
        ret
508
 
509
  .error:
510
        or      eax, -1
3556 hidnplayr 511
        DEBUGF  DEBUG_NETWORK_ERROR, "Adding network device failed\n"
3545 hidnplayr 512
        ret
513
 
514
 
515
 
6011 hidnplayr 516
;-----------------------------------------------------------------;
517
;                                                                 ;
518
; net_remove_device: Called by network driver to unregister dev.  ;
519
;                                                                 ;
520
;  IN:  ebx = ptr to device                                       ;
521
;                                                                 ;
522
;  OUT: eax: -1 on error                                          ;
523
;                                                                 ;
524
;-----------------------------------------------------------------;
3545 hidnplayr 525
align 4
6011 hidnplayr 526
net_remove_device:
3545 hidnplayr 527
 
7679 hidnplayr 528
        cmp     [net_device_count], 0
3545 hidnplayr 529
        je      .error
530
 
531
;----------------------------
532
; Find the driver in the list
533
 
534
        mov     eax, ebx
3600 hidnplayr 535
        mov     ecx, NET_DEVICES_MAX
7679 hidnplayr 536
        mov     edi, net_device_list
3545 hidnplayr 537
 
3711 clevermous 538
        repne scasd
3545 hidnplayr 539
        jnz     .error
540
 
541
;------------------------
542
; Remove it from the list
543
 
544
        xor     eax, eax
545
        mov     dword [edi-4], eax
7679 hidnplayr 546
        dec     [net_device_count]
3545 hidnplayr 547
 
6011 hidnplayr 548
        call    net_send_event
3545 hidnplayr 549
 
3601 hidnplayr 550
        xor     eax, eax
3545 hidnplayr 551
        ret
552
 
553
  .error:
554
        or      eax, -1
555
        ret
556
 
557
 
558
 
6011 hidnplayr 559
;-----------------------------------------------------------------;
560
;                                                                 ;
561
; net_ptr_to_num                                                  ;
562
;                                                                 ;
563
;  IN:  ebx = ptr to device struct                                ;
564
;                                                                 ;
565
;  OUT: edi = device number                                       ;
566
;       edi = -1 on error                                         ;
567
;                                                                 ;
568
;-----------------------------------------------------------------;
3545 hidnplayr 569
align 4
6011 hidnplayr 570
net_ptr_to_num:
3643 hidnplayr 571
 
6011 hidnplayr 572
        call    net_ptr_to_num4
3643 hidnplayr 573
        ror     edi, 2          ; If -1, stay -1
574
                                ; valid device numbers have last two bits 0, so do just shr
575
 
576
        ret
577
 
578
align 4
6011 hidnplayr 579
net_ptr_to_num4:                ; Todo, place number in device structure so we only need to verify?
3643 hidnplayr 580
 
5522 hidnplayr 581
        test    ebx, ebx
582
        jz      .fail
583
 
3545 hidnplayr 584
        push    ecx
3600 hidnplayr 585
        mov     ecx, NET_DEVICES_MAX
7679 hidnplayr 586
        mov     edi, net_device_list
3545 hidnplayr 587
  .loop:
588
        cmp     ebx, [edi]
3643 hidnplayr 589
        je      .found
3545 hidnplayr 590
        add     edi, 4
591
        dec     ecx
592
        jnz     .loop
593
 
5522 hidnplayr 594
        pop     ecx
595
  .fail:
3545 hidnplayr 596
        or      edi, -1
597
        ret
598
 
599
  .found:
7679 hidnplayr 600
        sub     edi, net_device_list
3545 hidnplayr 601
        pop     ecx
602
        ret
603
 
6011 hidnplayr 604
;-----------------------------------------------------------------;
605
;                                                                 ;
606
; checksum_1: Calculate semi-checksum for network packets.        ;
607
;                                                                 ;
608
;  IN:  edx = start offset for semi-checksum                      ;
609
;       esi = pointer to data                                     ;
610
;       ecx = data size                                           ;
611
;                                                                 ;
612
;  OUT: edx = semi-checksum                                       ;
613
;                                                                 ;
614
;-----------------------------------------------------------------;
3545 hidnplayr 615
align 4
616
checksum_1:
617
 
618
        shr     ecx, 1
619
        pushf
620
        jz      .no_2
621
 
622
        shr     ecx, 1
623
        pushf
624
        jz      .no_4
625
 
626
        shr     ecx, 1
627
        pushf
628
        jz      .no_8
629
 
630
  .loop:
631
        add     dl, [esi+1]
632
        adc     dh, [esi+0]
633
 
634
        adc     dl, [esi+3]
635
        adc     dh, [esi+2]
636
 
637
        adc     dl, [esi+5]
638
        adc     dh, [esi+4]
639
 
640
        adc     dl, [esi+7]
641
        adc     dh, [esi+6]
642
 
643
        adc     edx, 0
644
        add     esi, 8
645
 
646
        dec     ecx
647
        jnz     .loop
648
 
649
        adc     edx, 0
650
 
651
  .no_8:
652
        popf
653
        jnc     .no_4
654
 
655
        add     dl, [esi+1]
656
        adc     dh, [esi+0]
657
 
658
        adc     dl, [esi+3]
659
        adc     dh, [esi+2]
660
 
661
        adc     edx, 0
662
        add     esi, 4
663
 
664
  .no_4:
665
        popf
666
        jnc     .no_2
667
 
668
        add     dl, [esi+1]
669
        adc     dh, [esi+0]
670
 
671
        adc     edx, 0
672
        inc     esi
673
        inc     esi
674
 
675
  .no_2:
676
        popf
677
        jnc     .end
678
 
679
        add     dh, [esi+0]
680
        adc     edx, 0
681
  .end:
682
        ret
683
 
6011 hidnplayr 684
;-----------------------------------------------------------------;
685
;                                                                 ;
686
; checksum_2: Calculate the final ip/tcp/udp checksum.            ;
687
;                                                                 ;
688
;   IN: edx = semi-checksum                                       ;
689
;                                                                 ;
690
;  OUT: dx = checksum (in INET byte order)                        ;
691
;                                                                 ;
692
;-----------------------------------------------------------------;
3545 hidnplayr 693
align 4
694
checksum_2:
695
 
696
        mov     ecx, edx
697
        shr     ecx, 16
698
        and     edx, 0xffff
699
        add     edx, ecx
700
 
701
        mov     ecx, edx
702
        shr     ecx, 16
703
        add     dx, cx
704
        test    dx, dx          ; it seems that ZF is not set when CF is set :(
705
        not     dx
706
        jnz     .not_zero
707
        dec     dx
708
  .not_zero:
709
        xchg    dl, dh
710
 
3556 hidnplayr 711
        DEBUGF  DEBUG_NETWORK_VERBOSE, "Checksum: %x\n", dx
3545 hidnplayr 712
 
713
        ret
714
 
715
 
716
 
6011 hidnplayr 717
;-----------------------------------------------------------------;
718
;                                                                 ;
719
;  System function 74: Low level access to network devices.       ;
720
;                                                                 ;
721
;-----------------------------------------------------------------;
3545 hidnplayr 722
align 4
3601 hidnplayr 723
sys_network:
3545 hidnplayr 724
 
3879 hidnplayr 725
        cmp     bl, 255
3545 hidnplayr 726
        jne     @f
727
 
7679 hidnplayr 728
        mov     eax, [net_device_count]
3601 hidnplayr 729
        mov     [esp+32], eax
730
        ret
3545 hidnplayr 731
 
732
   @@:
7679 hidnplayr 733
        cmp     bh, NET_DEVICES_MAX                     ; Check if device number exists
3545 hidnplayr 734
        jae     .doesnt_exist
735
 
736
        mov     esi, ebx
737
        and     esi, 0x0000ff00
738
        shr     esi, 6
739
 
7679 hidnplayr 740
        cmp     dword[esi + net_device_list], 0         ; check if device is running
3545 hidnplayr 741
        je      .doesnt_exist
742
 
7679 hidnplayr 743
        mov     eax, [esi + net_device_list]
3545 hidnplayr 744
 
745
        and     ebx, 0x000000ff
746
        cmp     ebx, .number
747
        ja      .doesnt_exist
748
        jmp     dword [.table + 4*ebx]
749
 
750
  .table:
751
        dd      .get_type               ; 0
752
        dd      .get_dev_name           ; 1
753
        dd      .reset                  ; 2
754
        dd      .stop                   ; 3
755
        dd      .get_ptr                ; 4
756
        dd      .get_drv_name           ; 5
3601 hidnplayr 757
 
758
        dd      .packets_tx             ; 6
759
        dd      .packets_rx             ; 7
760
        dd      .bytes_tx               ; 8
761
        dd      .bytes_rx               ; 9
762
        dd      .state                  ; 10
3545 hidnplayr 763
  .number = ($ - .table) / 4 - 1
764
 
3601 hidnplayr 765
  .get_type:
3600 hidnplayr 766
        mov     eax, [eax + NET_DEVICE.device_type]
3601 hidnplayr 767
        mov     [esp+32], eax
768
        ret
3545 hidnplayr 769
 
3601 hidnplayr 770
  .get_dev_name:
8700 Coldy 771
; { Patch by Coldy, sanity check
772
        mov     ebx, eax ; eax will used for is_region_userspace return
773
        stdcall is_region_userspace, ecx, 64
774
        jz      .bad_buffer
775
        mov     esi, [ebx + NET_DEVICE.name] ;mov     esi, [eax + NET_DEVICE.name]
776
; } End patch by Coldy, sanity check
3545 hidnplayr 777
        mov     edi, ecx
778
 
779
        mov     ecx, 64/4 ; max length
3711 clevermous 780
        rep movsd
3545 hidnplayr 781
 
782
        xor     eax, eax
3601 hidnplayr 783
        mov     [esp+32], eax
784
        ret
3545 hidnplayr 785
 
3601 hidnplayr 786
  .reset:
3545 hidnplayr 787
        call    [eax + NET_DEVICE.reset]
3601 hidnplayr 788
        mov     [esp+32], eax
789
        ret
3545 hidnplayr 790
 
3601 hidnplayr 791
  .stop:
3545 hidnplayr 792
        call    [eax + NET_DEVICE.unload]
3601 hidnplayr 793
        mov     [esp+32], eax
794
        ret
3545 hidnplayr 795
 
796
 
3601 hidnplayr 797
  .get_ptr:
798
        mov     [esp+32], eax
799
        ret
3545 hidnplayr 800
 
801
 
3601 hidnplayr 802
  .get_drv_name:
803
        xor     eax, eax
804
        mov     [esp+32], eax
805
        ret
3545 hidnplayr 806
 
3601 hidnplayr 807
  .packets_tx:
808
        mov     eax, [eax + NET_DEVICE.packets_tx]
809
        mov     [esp+32], eax
810
        ret
3545 hidnplayr 811
 
3601 hidnplayr 812
  .packets_rx:
813
        mov     eax, [eax + NET_DEVICE.packets_rx]
814
        mov     [esp+32], eax
815
        ret
3545 hidnplayr 816
 
3601 hidnplayr 817
  .bytes_tx:
6011 hidnplayr 818
        mov     ebx, dword[eax + NET_DEVICE.bytes_tx + 4]
3601 hidnplayr 819
        mov     [esp+20], ebx
6011 hidnplayr 820
        mov     eax, dword[eax + NET_DEVICE.bytes_tx]
3601 hidnplayr 821
        mov     [esp+32], eax
822
        ret
3545 hidnplayr 823
 
3601 hidnplayr 824
  .bytes_rx:
6011 hidnplayr 825
        mov     ebx, dword[eax + NET_DEVICE.bytes_rx + 4]
3601 hidnplayr 826
        mov     [esp+20], ebx
6011 hidnplayr 827
        mov     eax, dword[eax + NET_DEVICE.bytes_rx]
3601 hidnplayr 828
        mov     [esp+32], eax
829
        ret
3545 hidnplayr 830
 
3601 hidnplayr 831
  .state:
832
        mov     eax, [eax + NET_DEVICE.link_state]
3545 hidnplayr 833
        mov     [esp+32], eax
834
        ret
835
 
836
 
3601 hidnplayr 837
  .doesnt_exist:
8700 Coldy 838
  .bad_buffer: ; Sanity check failed, exit
3601 hidnplayr 839
        mov     dword[esp+32], -1
840
        ret
841
 
842
 
843
 
6011 hidnplayr 844
;-----------------------------------------------------------------;
845
;                                                                 ;
846
;  System function 76: Low level access to protocol handlers.     ;
847
;                                                                 ;
848
;-----------------------------------------------------------------;
3545 hidnplayr 849
align 4
850
sys_protocols:
3600 hidnplayr 851
        cmp     bh, NET_DEVICES_MAX             ; Check if device number exists
3545 hidnplayr 852
        jae     .doesnt_exist
853
 
7963 hidnplayr 854
        mov     eax, ebx
855
        and     eax, 0x0000ff00
856
        shr     eax, 6                          ; now we have the device num * 4 in eax
857
        cmp     [eax + net_device_list], 0      ; check if device is running
3545 hidnplayr 858
        je      .doesnt_exist
859
 
860
        push    .return                         ; return address (we will be using jumps instead of calls)
861
 
862
        mov     eax, ebx                        ; set ax to protocol number
863
        shr     eax, 16                         ;
864
 
865
        cmp     ax, API_ETH
6011 hidnplayr 866
        je      eth_api
3545 hidnplayr 867
 
868
        cmp     ax, API_IPv4
6011 hidnplayr 869
        je      ipv4_api
3545 hidnplayr 870
 
871
        cmp     ax, API_ICMP
6011 hidnplayr 872
        je      icmp_api
3545 hidnplayr 873
 
874
        cmp     ax, API_UDP
6011 hidnplayr 875
        je      udp_api
3545 hidnplayr 876
 
877
        cmp     ax, API_TCP
6011 hidnplayr 878
        je      tcp_api
3545 hidnplayr 879
 
880
        cmp     ax, API_ARP
6011 hidnplayr 881
        je      arp_api
3545 hidnplayr 882
 
883
        cmp     ax, API_PPPOE
6011 hidnplayr 884
        je      pppoe_api
3545 hidnplayr 885
 
886
        cmp     ax, API_IPv6
6011 hidnplayr 887
        je      ipv6_api
3545 hidnplayr 888
 
889
        add     esp, 4                           ; if we reached here, no function was called, so we need to balance stack
890
 
891
  .doesnt_exist:
892
        mov     eax, -1
893
 
894
  .return:
895
        mov     [esp+28+4], eax                 ; return eax value to the program
896
        ret