Subversion Repositories Kolibri OS

Rev

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