Subversion Repositories Kolibri OS

Rev

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

Rev Author Line No. Line
3555 Serge 1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2
;;                                                                 ;;
5565 serge 3
;; Copyright (C) KolibriOS team 2004-2015. All rights reserved.    ;;
3555 Serge 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
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1 ha 23
 
593 mikedld 24
$Revision: 5984 $
1 ha 25
 
261 hidnplayr 26
uglobal
3555 Serge 27
        net_10ms        dd ?
28
        net_tmr_count   dw ?
261 hidnplayr 29
endg
1 ha 30
 
3589 Serge 31
DEBUG_NETWORK_ERROR     = 1
32
DEBUG_NETWORK_VERBOSE   = 0
33
 
3626 Serge 34
NET_DEVICES_MAX         = 16
5565 serge 35
NET_BUFFERS             = 512
36
NET_BUFFER_SIZE         = 2048
3555 Serge 37
ARP_BLOCK               = 1             ; true or false
1 ha 38
 
3626 Serge 39
EPHEMERAL_PORT_MIN      = 49152
40
EPHEMERAL_PORT_MAX      = 61000
3555 Serge 41
MIN_EPHEMERAL_PORT_N    = 0x00C0        ; same in Network byte order (FIXME)
42
MAX_EPHEMERAL_PORT_N    = 0x48EE        ; same in Network byte order (FIXME)
1 ha 43
 
3555 Serge 44
; Ethernet protocol numbers
3626 Serge 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
1 ha 50
 
3626 Serge 51
; Internet protocol numbers
52
IP_PROTO_IP             = 0
53
IP_PROTO_ICMP           = 1
54
IP_PROTO_TCP            = 6
55
IP_PROTO_UDP            = 17
5984 serge 56
IP_PROTO_RAW            = 255
3626 Serge 57
 
5984 serge 58
; IP options
59
IP_TOS                  = 1
60
IP_TTL                  = 2
61
IP_HDRINCL              = 3
62
 
3555 Serge 63
; PPP protocol numbers
3626 Serge 64
PPP_PROTO_IPv4          = 0x2100
65
PPP_PROTO_IPV6          = 0x5780
66
PPP_PROTO_ETHERNET      = 666           ; FIXME
1 ha 67
 
3555 Serge 68
;Protocol family
69
AF_UNSPEC               = 0
70
AF_LOCAL                = 1
71
AF_INET4                = 2
72
AF_INET6                = 10
3626 Serge 73
AF_PPP                  = 777           ; FIXME
907 mikedld 74
 
3555 Serge 75
; Socket types
76
SOCK_STREAM             = 1
77
SOCK_DGRAM              = 2
78
SOCK_RAW                = 3
1 ha 79
 
5984 serge 80
; Socket level
81
SOL_SOCKET              = 0xffff
82
 
3555 Serge 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
1 ha 94
 
3555 Serge 95
SO_NONBLOCK             = 1 shl 31
1 ha 96
 
3555 Serge 97
; Socket flags for user calls
98
MSG_PEEK                = 0x02
99
MSG_DONTWAIT            = 0x40
261 hidnplayr 100
 
3555 Serge 101
; Socket States
3626 Serge 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
261 hidnplayr 112
 
3725 Serge 113
SS_ASYNC                = 0x1000        ; async i/o notify
114
SS_ISCONFIRMING         = 0x2000        ; deciding to accept connection req
115
SS_MORETOCOME           = 0x4000
261 hidnplayr 116
 
3555 Serge 117
SS_BLOCKED              = 0x8000
1 ha 118
 
119
 
5201 serge 120
SOCKET_MAXDATA          = 4096*64       ; must be 4096*(power of 2) where 'power of 2' is at least 8
3626 Serge 121
MAX_backlog             = 20            ; maximum backlog for stream sockets
1 ha 122
 
3555 Serge 123
; Error Codes
3725 Serge 124
ENOBUFS                 = 1
4265 Serge 125
EINPROGRESS             = 2
3725 Serge 126
EOPNOTSUPP              = 4
127
EWOULDBLOCK             = 6
128
ENOTCONN                = 9
129
EALREADY                = 10
130
EINVAL                  = 11
131
EMSGSIZE                = 12
132
ENOMEM                  = 18
133
EADDRINUSE              = 20
3555 Serge 134
ECONNREFUSED            = 61
135
ECONNRESET              = 52
4265 Serge 136
EISCONN                 = 56
3555 Serge 137
ETIMEDOUT               = 60
138
ECONNABORTED            = 53
1 ha 139
 
3555 Serge 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
1 ha 149
 
3626 Serge 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)
5565 serge 156
NET_LINK_LOOPBACK       = 0
3626 Serge 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
4423 Serge 162
NET_HWACC_TCP_IPv4_IN   = 1 shl 0
163
NET_HWACC_TCP_IPv4_OUT  = 1 shl 1
1 ha 164
 
5565 serge 165
; Network frame types
166
NET_BUFF_LOOPBACK      = 0
167
NET_BUFF_ETH           = 1
168
 
3555 Serge 169
struct  NET_DEVICE
907 mikedld 170
 
3626 Serge 171
        device_type     dd ?    ; Type field
3555 Serge 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
 
3626 Serge 184
        link_state      dd ?    ; link state (0 = no link)
3555 Serge 185
        hwacc           dd ?    ; bitmask stating enabled HW accelerations (offload engines)
186
 
187
ends
188
 
5565 serge 189
struct  NET_BUFF
3555 Serge 190
 
5565 serge 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
 
3555 Serge 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
261 hidnplayr 211
}
212
 
3555 Serge 213
; Network to Hardware byte order (dword)
214
macro ntohd reg {
261 hidnplayr 215
 
3555 Serge 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
 
261 hidnplayr 230
include "queue.inc"
3555 Serge 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
 
261 hidnplayr 245
include "socket.inc"
246
 
247
 
1 ha 248
 
3725 Serge 249
uglobal
3555 Serge 250
align 4
909 mikedld 251
 
5565 serge 252
        NET_RUNNING     dd ?
253
        NET_DRV_LIST    rd NET_DEVICES_MAX
1 ha 254
 
5565 serge 255
        NET_BUFFS_FREE  rd NET_BUFFERS
256
        .current        dd ?
257
 
3555 Serge 258
endg
1 ha 259
 
260
 
3555 Serge 261
;-----------------------------------------------------------------
1 ha 262
;
3555 Serge 263
; stack_init
1 ha 264
;
3555 Serge 265
;  This function calls all network init procedures
266
;
267
;  IN:  /
268
;  OUT: /
269
;
270
;-----------------------------------------------------------------
1168 Lrz 271
align 4
3555 Serge 272
stack_init:
1 ha 273
 
5565 serge 274
; allocate network buffers
275
        stdcall kernel_alloc, NET_BUFFER_SIZE*NET_BUFFERS
276
        test    eax, eax
277
        jz      .fail
278
 
279
        mov     edi, NET_BUFFS_FREE
280
        mov     ecx, NET_BUFFERS
281
        cld
282
  .loop:
283
        stosd
284
        add     eax, NET_BUFFER_SIZE
285
        dec     ecx
286
        jnz     .loop
287
 
288
        mov     eax, NET_BUFFS_FREE
289
        stosd
290
 
3555 Serge 291
; Init the network drivers list
292
        xor     eax, eax
293
        mov     edi, NET_RUNNING
5565 serge 294
        mov     ecx, (NET_DEVICES_MAX + 1)
3725 Serge 295
        rep stosd
1 ha 296
 
4265 Serge 297
        ETH_init
298
 
3555 Serge 299
        PPPoE_init
1 ha 300
 
3555 Serge 301
        IPv4_init
302
;        IPv6_init
303
        ICMP_init
1 ha 304
 
3555 Serge 305
        ARP_init
306
        UDP_init
307
        TCP_init
1 ha 308
 
3555 Serge 309
        SOCKET_init
1 ha 310
 
3626 Serge 311
        LOOP_init
312
 
3555 Serge 313
        mov     [net_tmr_count], 0
5565 serge 314
        ret
1 ha 315
 
5565 serge 316
  .fail:
317
        DEBUGF  DEBUG_NETWORK_ERROR, "Stack init failed!\n"
2434 Serge 318
        ret
1 ha 319
 
320
 
321
 
3555 Serge 322
; Wakeup every tick.
323
proc stack_handler_has_work?
1 ha 324
 
3725 Serge 325
        mov     eax, [timer_ticks]
326
        cmp     eax, [net_10ms]
1 ha 327
 
2434 Serge 328
        ret
261 hidnplayr 329
endp
1 ha 330
 
3555 Serge 331
 
332
;-----------------------------------------------------------------
1 ha 333
;
3555 Serge 334
; stack_handler
1 ha 335
;
3555 Serge 336
;  This function is called in kernel loop
337
;
338
;  IN:  /
339
;  OUT: /
340
;
341
;-----------------------------------------------------------------
342
align 4
343
stack_handler:
261 hidnplayr 344
 
3555 Serge 345
        ; Test for 10ms tick
346
        mov     eax, [timer_ticks]
347
        cmp     eax, [net_10ms]
348
        je      .exit
349
        mov     [net_10ms], eax
261 hidnplayr 350
 
3555 Serge 351
        cmp     [NET_RUNNING], 0
352
        je      .exit
1 ha 353
 
3555 Serge 354
        test    [net_10ms], 0x0f        ; 160ms
355
        jnz     .exit
1 ha 356
 
3555 Serge 357
        TCP_timer_160ms
1 ha 358
 
3555 Serge 359
        test    [net_10ms], 0x3f        ; 640ms
360
        jnz     .exit
1 ha 361
 
3555 Serge 362
        ARP_decrease_entry_ttls
363
        IPv4_decrease_fragment_ttls
1 ha 364
 
5201 serge 365
        xor     edx, edx
366
        mov     eax, [TCP_timer1_event]
367
        mov     ebx, [eax + EVENT.id]
368
        xor     esi, esi
369
        call    raise_event
370
 
3555 Serge 371
  .exit:
372
        ret
1 ha 373
 
374
 
3908 Serge 375
align 4
5565 serge 376
proc NET_BUFF_alloc stdcall, buffersize
377
        cmp     [buffersize], NET_BUFFER_SIZE
378
        ja      .too_large
1 ha 379
 
5565 serge 380
        spin_lock_irqsave
3908 Serge 381
 
5565 serge 382
        mov     eax, [NET_BUFFS_FREE.current]
383
        cmp     eax, NET_BUFFS_FREE+NET_BUFFERS*4
384
        jae     .out_of_mem
385
        mov     eax, [eax]
386
        add     [NET_BUFFS_FREE.current], 4
387
 
388
        spin_unlock_irqrestore
389
 
390
        DEBUGF  DEBUG_NETWORK_VERBOSE, "net alloc: 0x%x\n", eax
391
        ret
392
 
393
  .out_of_mem:
394
        spin_unlock_irqrestore
395
 
396
        xor     eax, eax
397
        DEBUGF  DEBUG_NETWORK_ERROR, "NET_BUFF_alloc: out of mem!\n"
398
        ret
399
 
400
  .too_large:
401
        xor     eax, eax
402
        DEBUGF  DEBUG_NETWORK_ERROR, "NET_BUFF_alloc: too large!\n"
403
        ret
404
endp
405
 
406
 
3555 Serge 407
align 4
5565 serge 408
proc NET_BUFF_free stdcall, buffer
409
 
410
        DEBUGF  DEBUG_NETWORK_VERBOSE, "net free: 0x%x\n", [buffer]
411
 
412
        spin_lock_irqsave
413
 
414
        sub     [NET_BUFFS_FREE.current], 4
415
        mov     eax, [NET_BUFFS_FREE.current]
416
        push    [buffer]
417
        pop     dword[eax]
418
 
419
        spin_unlock_irqrestore
420
 
421
        ret
422
endp
423
 
424
 
425
align 4
3555 Serge 426
NET_link_changed:
323 hidnplayr 427
 
3626 Serge 428
        DEBUGF  DEBUG_NETWORK_VERBOSE, "NET_link_changed device=0x%x status=0x%x\n", ebx, [ebx + NET_DEVICE.link_state]
1 ha 429
 
3555 Serge 430
align 4
431
NET_send_event:
1 ha 432
 
3589 Serge 433
        DEBUGF  DEBUG_NETWORK_VERBOSE, "NET_send_event\n"
1 ha 434
 
3555 Serge 435
; Send event to all applications
436
        push    edi ecx
437
        mov     edi, SLOT_BASE
438
        mov     ecx, [TASK_COUNT]
439
  .loop:
440
        add     edi, 256
441
        or      [edi + APPDATA.event_mask], EVENT_NETWORK2
442
        loop    .loop
443
        pop     ecx edi
1 ha 444
 
3555 Serge 445
        ret
1 ha 446
 
447
 
448
 
3555 Serge 449
;-----------------------------------------------------------------
450
;
451
; NET_add_device:
452
;
453
;  This function is called by the network drivers,
454
;  to register each running NIC to the kernel
455
;
456
;  IN:  Pointer to device structure in ebx
457
;  OUT: Device num in eax, -1 on error
458
;
459
;-----------------------------------------------------------------
460
align 4
461
NET_add_device:
1 ha 462
 
3589 Serge 463
        DEBUGF  DEBUG_NETWORK_VERBOSE, "NET_Add_Device: %x\n", ebx   ;;; TODO: use mutex to lock net device list
1 ha 464
 
3626 Serge 465
        cmp     [NET_RUNNING], NET_DEVICES_MAX
3555 Serge 466
        jae     .error
1 ha 467
 
3555 Serge 468
;----------------------------------
469
; Check if device is already listed
470
        mov     eax, ebx
3626 Serge 471
        mov     ecx, NET_DEVICES_MAX    ; We need to check whole list because a device may be removed without re-organizing list
3555 Serge 472
        mov     edi, NET_DRV_LIST
1 ha 473
 
3725 Serge 474
        repne scasd                     ; See if device is already in the list
3555 Serge 475
        jz      .error
1 ha 476
 
3555 Serge 477
;----------------------------
478
; Find empty slot in the list
479
        xor     eax, eax
3626 Serge 480
        mov     ecx, NET_DEVICES_MAX
3555 Serge 481
        mov     edi, NET_DRV_LIST
1 ha 482
 
3725 Serge 483
        repne scasd
3555 Serge 484
        jnz     .error
1 ha 485
 
3555 Serge 486
        sub     edi, 4
1 ha 487
 
3555 Serge 488
;-----------------------------
489
; Add device to the found slot
490
        mov     [edi], ebx              ; add device to list
1 ha 491
 
3555 Serge 492
        mov     eax, edi                ; Calculate device number in eax
493
        sub     eax, NET_DRV_LIST
494
        shr     eax, 2
1 ha 495
 
3555 Serge 496
        inc     [NET_RUNNING]           ; Indicate that one more network device is up and running
1 ha 497
 
3555 Serge 498
        call    NET_send_event
1 ha 499
 
3589 Serge 500
        DEBUGF  DEBUG_NETWORK_VERBOSE, "Device number: %u\n", eax
2434 Serge 501
        ret
1 ha 502
 
3555 Serge 503
  .error:
504
        or      eax, -1
3589 Serge 505
        DEBUGF  DEBUG_NETWORK_ERROR, "Adding network device failed\n"
2434 Serge 506
        ret
261 hidnplayr 507
 
1 ha 508
 
509
 
3555 Serge 510
;-----------------------------------------------------------------
511
;
512
; NET_Remove_Device:
513
;
3626 Serge 514
;  This function is called by network drivers,
3555 Serge 515
;  to unregister network devices from the kernel
516
;
517
;  IN:  Pointer to device structure in ebx
518
;  OUT: eax: -1 on error
519
;
520
;-----------------------------------------------------------------
521
align 4
522
NET_remove_device:
379 serge 523
 
3555 Serge 524
        cmp     [NET_RUNNING], 0
525
        je      .error
261 hidnplayr 526
 
3555 Serge 527
;----------------------------
528
; Find the driver in the list
379 serge 529
 
3555 Serge 530
        mov     eax, ebx
3626 Serge 531
        mov     ecx, NET_DEVICES_MAX
532
        mov     edi, NET_DRV_LIST
261 hidnplayr 533
 
3725 Serge 534
        repne scasd
3555 Serge 535
        jnz     .error
379 serge 536
 
3555 Serge 537
;------------------------
538
; Remove it from the list
379 serge 539
 
3555 Serge 540
        xor     eax, eax
541
        mov     dword [edi-4], eax
3626 Serge 542
        dec     [NET_RUNNING]
3555 Serge 543
 
544
        call    NET_send_event
545
 
3626 Serge 546
        xor     eax, eax
1369 Lrz 547
        ret
379 serge 548
 
3555 Serge 549
  .error:
550
        or      eax, -1
1369 Lrz 551
        ret
379 serge 552
 
261 hidnplayr 553
 
1 ha 554
 
3555 Serge 555
;-----------------------------------------------------------------
1 ha 556
;
3555 Serge 557
; NET_ptr_to_num
1 ha 558
;
3555 Serge 559
; IN:  ebx = ptr to device struct
560
; OUT: edi = -1 on error, device number otherwise
561
;
562
;-----------------------------------------------------------------
1369 Lrz 563
align 4
3555 Serge 564
NET_ptr_to_num:
3725 Serge 565
 
566
        call    NET_ptr_to_num4
567
        ror     edi, 2          ; If -1, stay -1
568
                                ; valid device numbers have last two bits 0, so do just shr
569
 
570
        ret
571
 
572
align 4
573
NET_ptr_to_num4:                ; Todo, place number in device structure so we only need to verify?
574
 
5565 serge 575
        test    ebx, ebx
576
        jz      .fail
577
 
3555 Serge 578
        push    ecx
3626 Serge 579
        mov     ecx, NET_DEVICES_MAX
3555 Serge 580
        mov     edi, NET_DRV_LIST
581
  .loop:
582
        cmp     ebx, [edi]
3725 Serge 583
        je      .found
3555 Serge 584
        add     edi, 4
585
        dec     ecx
586
        jnz     .loop
1 ha 587
 
5565 serge 588
        pop     ecx
589
  .fail:
3555 Serge 590
        or      edi, -1
2434 Serge 591
        ret
1 ha 592
 
3555 Serge 593
  .found:
594
        sub     edi, NET_DRV_LIST
595
        pop     ecx
2434 Serge 596
        ret
1 ha 597
 
3555 Serge 598
;-----------------------------------------------------------------
1 ha 599
;
3555 Serge 600
; checksum_1
1 ha 601
;
3555 Serge 602
;  This is the first of two functions needed to calculate a checksum.
603
;
604
;  IN:  edx = start offset for semi-checksum
605
;       esi = pointer to data
606
;       ecx = data size
607
;  OUT: edx = semi-checksum
608
;
609
;
610
; Code was optimized by diamond
611
;
612
;-----------------------------------------------------------------
613
align 4
614
checksum_1:
1369 Lrz 615
 
3555 Serge 616
        shr     ecx, 1
617
        pushf
618
        jz      .no_2
1369 Lrz 619
 
3555 Serge 620
        shr     ecx, 1
621
        pushf
622
        jz      .no_4
1369 Lrz 623
 
3555 Serge 624
        shr     ecx, 1
625
        pushf
626
        jz      .no_8
1369 Lrz 627
 
3555 Serge 628
  .loop:
629
        add     dl, [esi+1]
630
        adc     dh, [esi+0]
1 ha 631
 
3555 Serge 632
        adc     dl, [esi+3]
633
        adc     dh, [esi+2]
1 ha 634
 
3555 Serge 635
        adc     dl, [esi+5]
636
        adc     dh, [esi+4]
1 ha 637
 
3555 Serge 638
        adc     dl, [esi+7]
639
        adc     dh, [esi+6]
1 ha 640
 
3555 Serge 641
        adc     edx, 0
642
        add     esi, 8
1 ha 643
 
3555 Serge 644
        dec     ecx
645
        jnz     .loop
1 ha 646
 
3555 Serge 647
        adc     edx, 0
1 ha 648
 
3555 Serge 649
  .no_8:
650
        popf
651
        jnc     .no_4
1 ha 652
 
3555 Serge 653
        add     dl, [esi+1]
654
        adc     dh, [esi+0]
1 ha 655
 
3555 Serge 656
        adc     dl, [esi+3]
657
        adc     dh, [esi+2]
1 ha 658
 
3555 Serge 659
        adc     edx, 0
660
        add     esi, 4
1 ha 661
 
3555 Serge 662
  .no_4:
663
        popf
664
        jnc     .no_2
1 ha 665
 
3555 Serge 666
        add     dl, [esi+1]
667
        adc     dh, [esi+0]
1 ha 668
 
3555 Serge 669
        adc     edx, 0
670
        inc     esi
671
        inc     esi
1 ha 672
 
3555 Serge 673
  .no_2:
674
        popf
675
        jnc     .end
1 ha 676
 
3555 Serge 677
        add     dh, [esi+0]
678
        adc     edx, 0
679
  .end:
2434 Serge 680
        ret
1 ha 681
 
3555 Serge 682
;-----------------------------------------------------------------
683
;
684
; checksum_2
685
;
686
;  This function calculates the final ip/tcp/udp checksum for you
687
;
688
;  IN:  edx = semi-checksum
689
;  OUT: dx = checksum (in INET byte order)
690
;
691
;-----------------------------------------------------------------
692
align 4
693
checksum_2:
1 ha 694
 
3555 Serge 695
        mov     ecx, edx
696
        shr     ecx, 16
697
        and     edx, 0xffff
698
        add     edx, ecx
1 ha 699
 
3555 Serge 700
        mov     ecx, edx
701
        shr     ecx, 16
702
        add     dx, cx
703
        test    dx, dx          ; it seems that ZF is not set when CF is set :(
704
        not     dx
705
        jnz     .not_zero
706
        dec     dx
707
  .not_zero:
708
        xchg    dl, dh
1 ha 709
 
3589 Serge 710
        DEBUGF  DEBUG_NETWORK_VERBOSE, "Checksum: %x\n", dx
3555 Serge 711
 
2434 Serge 712
        ret
1 ha 713
 
714
 
715
 
3555 Serge 716
;----------------------------------------------------------------
717
;
3626 Serge 718
;  System function to work with network devices (74)
3555 Serge 719
;
720
;----------------------------------------------------------------
721
align 4
3626 Serge 722
sys_network:
1 ha 723
 
3908 Serge 724
        cmp     bl, 255
3555 Serge 725
        jne     @f
1 ha 726
 
3555 Serge 727
        mov     eax, [NET_RUNNING]
3626 Serge 728
        mov     [esp+32], eax
729
        ret
1 ha 730
 
3555 Serge 731
   @@:
3626 Serge 732
        cmp     bh, NET_DEVICES_MAX             ; Check if device number exists
3555 Serge 733
        jae     .doesnt_exist
1 ha 734
 
3555 Serge 735
        mov     esi, ebx
736
        and     esi, 0x0000ff00
737
        shr     esi, 6
1 ha 738
 
3555 Serge 739
        cmp     dword [esi + NET_DRV_LIST], 0   ; check if driver is running
740
        je      .doesnt_exist
1 ha 741
 
3555 Serge 742
        mov     eax, [esi + NET_DRV_LIST]
1 ha 743
 
3555 Serge 744
        and     ebx, 0x000000ff
745
        cmp     ebx, .number
746
        ja      .doesnt_exist
747
        jmp     dword [.table + 4*ebx]
1 ha 748
 
3555 Serge 749
  .table:
750
        dd      .get_type               ; 0
751
        dd      .get_dev_name           ; 1
752
        dd      .reset                  ; 2
753
        dd      .stop                   ; 3
754
        dd      .get_ptr                ; 4
755
        dd      .get_drv_name           ; 5
3626 Serge 756
 
757
        dd      .packets_tx             ; 6
758
        dd      .packets_rx             ; 7
759
        dd      .bytes_tx               ; 8
760
        dd      .bytes_rx               ; 9
761
        dd      .state                  ; 10
3555 Serge 762
  .number = ($ - .table) / 4 - 1
1 ha 763
 
3626 Serge 764
  .get_type:
765
        mov     eax, [eax + NET_DEVICE.device_type]
766
        mov     [esp+32], eax
767
        ret
1 ha 768
 
3626 Serge 769
  .get_dev_name:
3555 Serge 770
        mov     esi, [eax + NET_DEVICE.name]
771
        mov     edi, ecx
1 ha 772
 
3555 Serge 773
        mov     ecx, 64/4 ; max length
3725 Serge 774
        rep movsd
3555 Serge 775
 
2434 Serge 776
        xor     eax, eax
3626 Serge 777
        mov     [esp+32], eax
778
        ret
1 ha 779
 
3626 Serge 780
  .reset:
3555 Serge 781
        call    [eax + NET_DEVICE.reset]
3626 Serge 782
        mov     [esp+32], eax
783
        ret
1 ha 784
 
3626 Serge 785
  .stop:
3555 Serge 786
        call    [eax + NET_DEVICE.unload]
3626 Serge 787
        mov     [esp+32], eax
788
        ret
1 ha 789
 
790
 
3626 Serge 791
  .get_ptr:
792
        mov     [esp+32], eax
793
        ret
1 ha 794
 
795
 
3626 Serge 796
  .get_drv_name:
2434 Serge 797
        xor     eax, eax
3626 Serge 798
        mov     [esp+32], eax
799
        ret
3555 Serge 800
 
3626 Serge 801
  .packets_tx:
802
        mov     eax, [eax + NET_DEVICE.packets_tx]
803
        mov     [esp+32], eax
804
        ret
3555 Serge 805
 
3626 Serge 806
  .packets_rx:
807
        mov     eax, [eax + NET_DEVICE.packets_rx]
808
        mov     [esp+32], eax
809
        ret
3555 Serge 810
 
3626 Serge 811
  .bytes_tx:
812
        mov     ebx, dword [eax + NET_DEVICE.bytes_tx + 4]
813
        mov     [esp+20], ebx
814
        mov     eax, dword [eax + NET_DEVICE.bytes_tx]
815
        mov     [esp+32], eax
816
        ret
3555 Serge 817
 
3626 Serge 818
  .bytes_rx:
819
        mov     ebx, dword [eax + NET_DEVICE.bytes_rx + 4]
820
        mov     [esp+20], ebx
821
        mov     eax, dword [eax + NET_DEVICE.bytes_rx]
822
        mov     [esp+32], eax
823
        ret
3555 Serge 824
 
3626 Serge 825
  .state:
826
        mov     eax, [eax + NET_DEVICE.link_state]
3555 Serge 827
        mov     [esp+32], eax
2434 Serge 828
        ret
1 ha 829
 
830
 
3626 Serge 831
  .doesnt_exist:
832
        mov     dword[esp+32], -1
833
        ret
834
 
835
 
836
 
3555 Serge 837
;----------------------------------------------------------------
1 ha 838
;
3555 Serge 839
;  System function to work with protocols  (76)
1 ha 840
;
3555 Serge 841
;----------------------------------------------------------------
842
align 4
843
sys_protocols:
3626 Serge 844
        cmp     bh, NET_DEVICES_MAX             ; Check if device number exists
3555 Serge 845
        jae     .doesnt_exist
1 ha 846
 
3555 Serge 847
        mov     esi, ebx
848
        and     esi, 0x0000ff00
849
        shr     esi, 6                          ; now we have the device num * 4 in esi
850
        cmp     [esi + NET_DRV_LIST], 0         ; check if driver is running
851
        je      .doesnt_exist
1 ha 852
 
3555 Serge 853
        push    .return                         ; return address (we will be using jumps instead of calls)
1 ha 854
 
3555 Serge 855
        mov     eax, ebx                        ; set ax to protocol number
856
        shr     eax, 16                         ;
1 ha 857
 
3555 Serge 858
        cmp     ax, API_ETH
859
        je      ETH_api
1 ha 860
 
3555 Serge 861
        cmp     ax, API_IPv4
862
        je      IPv4_api
1 ha 863
 
3555 Serge 864
        cmp     ax, API_ICMP
865
        je      ICMP_api
1 ha 866
 
3555 Serge 867
        cmp     ax, API_UDP
868
        je      UDP_api
1 ha 869
 
3555 Serge 870
        cmp     ax, API_TCP
871
        je      TCP_api
1 ha 872
 
3555 Serge 873
        cmp     ax, API_ARP
874
        je      ARP_api
1 ha 875
 
3555 Serge 876
        cmp     ax, API_PPPOE
877
        je      PPPoE_api
1 ha 878
 
3555 Serge 879
        cmp     ax, API_IPv6
880
        je      IPv6_api
1 ha 881
 
3555 Serge 882
        add     esp, 4                           ; if we reached here, no function was called, so we need to balance stack
1 ha 883
 
3555 Serge 884
  .doesnt_exist:
885
        mov     eax, -1
1 ha 886
 
3555 Serge 887
  .return:
888
        mov     [esp+28+4], eax                 ; return eax value to the program
2434 Serge 889
        ret