Subversion Repositories Kolibri OS

Rev

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

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