Subversion Repositories Kolibri OS

Rev

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

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