Subversion Repositories Kolibri OS

Rev

Rev 5201 | Rev 5984 | 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: 5565 $
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
56
 
3555 Serge 57
; PPP protocol numbers
3626 Serge 58
PPP_PROTO_IPv4          = 0x2100
59
PPP_PROTO_IPV6          = 0x5780
60
PPP_PROTO_ETHERNET      = 666           ; FIXME
1 ha 61
 
3555 Serge 62
;Protocol family
63
AF_UNSPEC               = 0
64
AF_LOCAL                = 1
65
AF_INET4                = 2
66
AF_INET6                = 10
3626 Serge 67
AF_PPP                  = 777           ; FIXME
907 mikedld 68
 
3555 Serge 69
; Socket types
70
SOCK_STREAM             = 1
71
SOCK_DGRAM              = 2
72
SOCK_RAW                = 3
1 ha 73
 
3555 Serge 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
1 ha 85
 
3555 Serge 86
SO_NONBLOCK             = 1 shl 31
1 ha 87
 
3555 Serge 88
; Socket flags for user calls
89
MSG_PEEK                = 0x02
90
MSG_DONTWAIT            = 0x40
261 hidnplayr 91
 
3555 Serge 92
; Socket level
93
SOL_SOCKET              = 0
261 hidnplayr 94
 
95
 
3555 Serge 96
; Socket States
3626 Serge 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
261 hidnplayr 107
 
3725 Serge 108
SS_ASYNC                = 0x1000        ; async i/o notify
109
SS_ISCONFIRMING         = 0x2000        ; deciding to accept connection req
110
SS_MORETOCOME           = 0x4000
261 hidnplayr 111
 
3555 Serge 112
SS_BLOCKED              = 0x8000
1 ha 113
 
114
 
5201 serge 115
SOCKET_MAXDATA          = 4096*64       ; must be 4096*(power of 2) where 'power of 2' is at least 8
3626 Serge 116
MAX_backlog             = 20            ; maximum backlog for stream sockets
1 ha 117
 
3555 Serge 118
; Error Codes
3725 Serge 119
ENOBUFS                 = 1
4265 Serge 120
EINPROGRESS             = 2
3725 Serge 121
EOPNOTSUPP              = 4
122
EWOULDBLOCK             = 6
123
ENOTCONN                = 9
124
EALREADY                = 10
125
EINVAL                  = 11
126
EMSGSIZE                = 12
127
ENOMEM                  = 18
128
EADDRINUSE              = 20
3555 Serge 129
ECONNREFUSED            = 61
130
ECONNRESET              = 52
4265 Serge 131
EISCONN                 = 56
3555 Serge 132
ETIMEDOUT               = 60
133
ECONNABORTED            = 53
1 ha 134
 
3555 Serge 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
1 ha 144
 
3626 Serge 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)
5565 serge 151
NET_LINK_LOOPBACK       = 0
3626 Serge 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
4423 Serge 157
NET_HWACC_TCP_IPv4_IN   = 1 shl 0
158
NET_HWACC_TCP_IPv4_OUT  = 1 shl 1
1 ha 159
 
5565 serge 160
; Network frame types
161
NET_BUFF_LOOPBACK      = 0
162
NET_BUFF_ETH           = 1
163
 
3555 Serge 164
struct  NET_DEVICE
907 mikedld 165
 
3626 Serge 166
        device_type     dd ?    ; Type field
3555 Serge 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
 
3626 Serge 179
        link_state      dd ?    ; link state (0 = no link)
3555 Serge 180
        hwacc           dd ?    ; bitmask stating enabled HW accelerations (offload engines)
181
 
182
ends
183
 
5565 serge 184
struct  NET_BUFF
3555 Serge 185
 
5565 serge 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
 
3555 Serge 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
261 hidnplayr 206
}
207
 
3555 Serge 208
; Network to Hardware byte order (dword)
209
macro ntohd reg {
261 hidnplayr 210
 
3555 Serge 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
 
261 hidnplayr 225
include "queue.inc"
3555 Serge 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
 
261 hidnplayr 240
include "socket.inc"
241
 
242
 
1 ha 243
 
3725 Serge 244
uglobal
3555 Serge 245
align 4
909 mikedld 246
 
5565 serge 247
        NET_RUNNING     dd ?
248
        NET_DRV_LIST    rd NET_DEVICES_MAX
1 ha 249
 
5565 serge 250
        NET_BUFFS_FREE  rd NET_BUFFERS
251
        .current        dd ?
252
 
3555 Serge 253
endg
1 ha 254
 
255
 
3555 Serge 256
;-----------------------------------------------------------------
1 ha 257
;
3555 Serge 258
; stack_init
1 ha 259
;
3555 Serge 260
;  This function calls all network init procedures
261
;
262
;  IN:  /
263
;  OUT: /
264
;
265
;-----------------------------------------------------------------
1168 Lrz 266
align 4
3555 Serge 267
stack_init:
1 ha 268
 
5565 serge 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
 
3555 Serge 286
; Init the network drivers list
287
        xor     eax, eax
288
        mov     edi, NET_RUNNING
5565 serge 289
        mov     ecx, (NET_DEVICES_MAX + 1)
3725 Serge 290
        rep stosd
1 ha 291
 
4265 Serge 292
        ETH_init
293
 
3555 Serge 294
        PPPoE_init
1 ha 295
 
3555 Serge 296
        IPv4_init
297
;        IPv6_init
298
        ICMP_init
1 ha 299
 
3555 Serge 300
        ARP_init
301
        UDP_init
302
        TCP_init
1 ha 303
 
3555 Serge 304
        SOCKET_init
1 ha 305
 
3626 Serge 306
        LOOP_init
307
 
3555 Serge 308
        mov     [net_tmr_count], 0
5565 serge 309
        ret
1 ha 310
 
5565 serge 311
  .fail:
312
        DEBUGF  DEBUG_NETWORK_ERROR, "Stack init failed!\n"
2434 Serge 313
        ret
1 ha 314
 
315
 
316
 
3555 Serge 317
; Wakeup every tick.
318
proc stack_handler_has_work?
1 ha 319
 
3725 Serge 320
        mov     eax, [timer_ticks]
321
        cmp     eax, [net_10ms]
1 ha 322
 
2434 Serge 323
        ret
261 hidnplayr 324
endp
1 ha 325
 
3555 Serge 326
 
327
;-----------------------------------------------------------------
1 ha 328
;
3555 Serge 329
; stack_handler
1 ha 330
;
3555 Serge 331
;  This function is called in kernel loop
332
;
333
;  IN:  /
334
;  OUT: /
335
;
336
;-----------------------------------------------------------------
337
align 4
338
stack_handler:
261 hidnplayr 339
 
3555 Serge 340
        ; Test for 10ms tick
341
        mov     eax, [timer_ticks]
342
        cmp     eax, [net_10ms]
343
        je      .exit
344
        mov     [net_10ms], eax
261 hidnplayr 345
 
3555 Serge 346
        cmp     [NET_RUNNING], 0
347
        je      .exit
1 ha 348
 
3555 Serge 349
        test    [net_10ms], 0x0f        ; 160ms
350
        jnz     .exit
1 ha 351
 
3555 Serge 352
        TCP_timer_160ms
1 ha 353
 
3555 Serge 354
        test    [net_10ms], 0x3f        ; 640ms
355
        jnz     .exit
1 ha 356
 
3555 Serge 357
        ARP_decrease_entry_ttls
358
        IPv4_decrease_fragment_ttls
1 ha 359
 
5201 serge 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
 
3555 Serge 366
  .exit:
367
        ret
1 ha 368
 
369
 
3908 Serge 370
align 4
5565 serge 371
proc NET_BUFF_alloc stdcall, buffersize
372
        cmp     [buffersize], NET_BUFFER_SIZE
373
        ja      .too_large
1 ha 374
 
5565 serge 375
        spin_lock_irqsave
3908 Serge 376
 
5565 serge 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  DEBUG_NETWORK_VERBOSE, "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
 
3555 Serge 402
align 4
5565 serge 403
proc NET_BUFF_free stdcall, buffer
404
 
405
        DEBUGF  DEBUG_NETWORK_VERBOSE, "net free: 0x%x\n", [buffer]
406
 
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
 
420
align 4
3555 Serge 421
NET_link_changed:
323 hidnplayr 422
 
3626 Serge 423
        DEBUGF  DEBUG_NETWORK_VERBOSE, "NET_link_changed device=0x%x status=0x%x\n", ebx, [ebx + NET_DEVICE.link_state]
1 ha 424
 
3555 Serge 425
align 4
426
NET_send_event:
1 ha 427
 
3589 Serge 428
        DEBUGF  DEBUG_NETWORK_VERBOSE, "NET_send_event\n"
1 ha 429
 
3555 Serge 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
1 ha 439
 
3555 Serge 440
        ret
1 ha 441
 
442
 
443
 
3555 Serge 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:
1 ha 457
 
3589 Serge 458
        DEBUGF  DEBUG_NETWORK_VERBOSE, "NET_Add_Device: %x\n", ebx   ;;; TODO: use mutex to lock net device list
1 ha 459
 
3626 Serge 460
        cmp     [NET_RUNNING], NET_DEVICES_MAX
3555 Serge 461
        jae     .error
1 ha 462
 
3555 Serge 463
;----------------------------------
464
; Check if device is already listed
465
        mov     eax, ebx
3626 Serge 466
        mov     ecx, NET_DEVICES_MAX    ; We need to check whole list because a device may be removed without re-organizing list
3555 Serge 467
        mov     edi, NET_DRV_LIST
1 ha 468
 
3725 Serge 469
        repne scasd                     ; See if device is already in the list
3555 Serge 470
        jz      .error
1 ha 471
 
3555 Serge 472
;----------------------------
473
; Find empty slot in the list
474
        xor     eax, eax
3626 Serge 475
        mov     ecx, NET_DEVICES_MAX
3555 Serge 476
        mov     edi, NET_DRV_LIST
1 ha 477
 
3725 Serge 478
        repne scasd
3555 Serge 479
        jnz     .error
1 ha 480
 
3555 Serge 481
        sub     edi, 4
1 ha 482
 
3555 Serge 483
;-----------------------------
484
; Add device to the found slot
485
        mov     [edi], ebx              ; add device to list
1 ha 486
 
3555 Serge 487
        mov     eax, edi                ; Calculate device number in eax
488
        sub     eax, NET_DRV_LIST
489
        shr     eax, 2
1 ha 490
 
3555 Serge 491
        inc     [NET_RUNNING]           ; Indicate that one more network device is up and running
1 ha 492
 
3555 Serge 493
        call    NET_send_event
1 ha 494
 
3589 Serge 495
        DEBUGF  DEBUG_NETWORK_VERBOSE, "Device number: %u\n", eax
2434 Serge 496
        ret
1 ha 497
 
3555 Serge 498
  .error:
499
        or      eax, -1
3589 Serge 500
        DEBUGF  DEBUG_NETWORK_ERROR, "Adding network device failed\n"
2434 Serge 501
        ret
261 hidnplayr 502
 
1 ha 503
 
504
 
3555 Serge 505
;-----------------------------------------------------------------
506
;
507
; NET_Remove_Device:
508
;
3626 Serge 509
;  This function is called by network drivers,
3555 Serge 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:
379 serge 518
 
3555 Serge 519
        cmp     [NET_RUNNING], 0
520
        je      .error
261 hidnplayr 521
 
3555 Serge 522
;----------------------------
523
; Find the driver in the list
379 serge 524
 
3555 Serge 525
        mov     eax, ebx
3626 Serge 526
        mov     ecx, NET_DEVICES_MAX
527
        mov     edi, NET_DRV_LIST
261 hidnplayr 528
 
3725 Serge 529
        repne scasd
3555 Serge 530
        jnz     .error
379 serge 531
 
3555 Serge 532
;------------------------
533
; Remove it from the list
379 serge 534
 
3555 Serge 535
        xor     eax, eax
536
        mov     dword [edi-4], eax
3626 Serge 537
        dec     [NET_RUNNING]
3555 Serge 538
 
539
        call    NET_send_event
540
 
3626 Serge 541
        xor     eax, eax
1369 Lrz 542
        ret
379 serge 543
 
3555 Serge 544
  .error:
545
        or      eax, -1
1369 Lrz 546
        ret
379 serge 547
 
261 hidnplayr 548
 
1 ha 549
 
3555 Serge 550
;-----------------------------------------------------------------
1 ha 551
;
3555 Serge 552
; NET_ptr_to_num
1 ha 553
;
3555 Serge 554
; IN:  ebx = ptr to device struct
555
; OUT: edi = -1 on error, device number otherwise
556
;
557
;-----------------------------------------------------------------
1369 Lrz 558
align 4
3555 Serge 559
NET_ptr_to_num:
3725 Serge 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
 
5565 serge 570
        test    ebx, ebx
571
        jz      .fail
572
 
3555 Serge 573
        push    ecx
3626 Serge 574
        mov     ecx, NET_DEVICES_MAX
3555 Serge 575
        mov     edi, NET_DRV_LIST
576
  .loop:
577
        cmp     ebx, [edi]
3725 Serge 578
        je      .found
3555 Serge 579
        add     edi, 4
580
        dec     ecx
581
        jnz     .loop
1 ha 582
 
5565 serge 583
        pop     ecx
584
  .fail:
3555 Serge 585
        or      edi, -1
2434 Serge 586
        ret
1 ha 587
 
3555 Serge 588
  .found:
589
        sub     edi, NET_DRV_LIST
590
        pop     ecx
2434 Serge 591
        ret
1 ha 592
 
3555 Serge 593
;-----------------------------------------------------------------
1 ha 594
;
3555 Serge 595
; checksum_1
1 ha 596
;
3555 Serge 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:
1369 Lrz 610
 
3555 Serge 611
        shr     ecx, 1
612
        pushf
613
        jz      .no_2
1369 Lrz 614
 
3555 Serge 615
        shr     ecx, 1
616
        pushf
617
        jz      .no_4
1369 Lrz 618
 
3555 Serge 619
        shr     ecx, 1
620
        pushf
621
        jz      .no_8
1369 Lrz 622
 
3555 Serge 623
  .loop:
624
        add     dl, [esi+1]
625
        adc     dh, [esi+0]
1 ha 626
 
3555 Serge 627
        adc     dl, [esi+3]
628
        adc     dh, [esi+2]
1 ha 629
 
3555 Serge 630
        adc     dl, [esi+5]
631
        adc     dh, [esi+4]
1 ha 632
 
3555 Serge 633
        adc     dl, [esi+7]
634
        adc     dh, [esi+6]
1 ha 635
 
3555 Serge 636
        adc     edx, 0
637
        add     esi, 8
1 ha 638
 
3555 Serge 639
        dec     ecx
640
        jnz     .loop
1 ha 641
 
3555 Serge 642
        adc     edx, 0
1 ha 643
 
3555 Serge 644
  .no_8:
645
        popf
646
        jnc     .no_4
1 ha 647
 
3555 Serge 648
        add     dl, [esi+1]
649
        adc     dh, [esi+0]
1 ha 650
 
3555 Serge 651
        adc     dl, [esi+3]
652
        adc     dh, [esi+2]
1 ha 653
 
3555 Serge 654
        adc     edx, 0
655
        add     esi, 4
1 ha 656
 
3555 Serge 657
  .no_4:
658
        popf
659
        jnc     .no_2
1 ha 660
 
3555 Serge 661
        add     dl, [esi+1]
662
        adc     dh, [esi+0]
1 ha 663
 
3555 Serge 664
        adc     edx, 0
665
        inc     esi
666
        inc     esi
1 ha 667
 
3555 Serge 668
  .no_2:
669
        popf
670
        jnc     .end
1 ha 671
 
3555 Serge 672
        add     dh, [esi+0]
673
        adc     edx, 0
674
  .end:
2434 Serge 675
        ret
1 ha 676
 
3555 Serge 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:
1 ha 689
 
3555 Serge 690
        mov     ecx, edx
691
        shr     ecx, 16
692
        and     edx, 0xffff
693
        add     edx, ecx
1 ha 694
 
3555 Serge 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
1 ha 704
 
3589 Serge 705
        DEBUGF  DEBUG_NETWORK_VERBOSE, "Checksum: %x\n", dx
3555 Serge 706
 
2434 Serge 707
        ret
1 ha 708
 
709
 
710
 
3555 Serge 711
;----------------------------------------------------------------
712
;
3626 Serge 713
;  System function to work with network devices (74)
3555 Serge 714
;
715
;----------------------------------------------------------------
716
align 4
3626 Serge 717
sys_network:
1 ha 718
 
3908 Serge 719
        cmp     bl, 255
3555 Serge 720
        jne     @f
1 ha 721
 
3555 Serge 722
        mov     eax, [NET_RUNNING]
3626 Serge 723
        mov     [esp+32], eax
724
        ret
1 ha 725
 
3555 Serge 726
   @@:
3626 Serge 727
        cmp     bh, NET_DEVICES_MAX             ; Check if device number exists
3555 Serge 728
        jae     .doesnt_exist
1 ha 729
 
3555 Serge 730
        mov     esi, ebx
731
        and     esi, 0x0000ff00
732
        shr     esi, 6
1 ha 733
 
3555 Serge 734
        cmp     dword [esi + NET_DRV_LIST], 0   ; check if driver is running
735
        je      .doesnt_exist
1 ha 736
 
3555 Serge 737
        mov     eax, [esi + NET_DRV_LIST]
1 ha 738
 
3555 Serge 739
        and     ebx, 0x000000ff
740
        cmp     ebx, .number
741
        ja      .doesnt_exist
742
        jmp     dword [.table + 4*ebx]
1 ha 743
 
3555 Serge 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
3626 Serge 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
3555 Serge 757
  .number = ($ - .table) / 4 - 1
1 ha 758
 
3626 Serge 759
  .get_type:
760
        mov     eax, [eax + NET_DEVICE.device_type]
761
        mov     [esp+32], eax
762
        ret
1 ha 763
 
3626 Serge 764
  .get_dev_name:
3555 Serge 765
        mov     esi, [eax + NET_DEVICE.name]
766
        mov     edi, ecx
1 ha 767
 
3555 Serge 768
        mov     ecx, 64/4 ; max length
3725 Serge 769
        rep movsd
3555 Serge 770
 
2434 Serge 771
        xor     eax, eax
3626 Serge 772
        mov     [esp+32], eax
773
        ret
1 ha 774
 
3626 Serge 775
  .reset:
3555 Serge 776
        call    [eax + NET_DEVICE.reset]
3626 Serge 777
        mov     [esp+32], eax
778
        ret
1 ha 779
 
3626 Serge 780
  .stop:
3555 Serge 781
        call    [eax + NET_DEVICE.unload]
3626 Serge 782
        mov     [esp+32], eax
783
        ret
1 ha 784
 
785
 
3626 Serge 786
  .get_ptr:
787
        mov     [esp+32], eax
788
        ret
1 ha 789
 
790
 
3626 Serge 791
  .get_drv_name:
2434 Serge 792
        xor     eax, eax
3626 Serge 793
        mov     [esp+32], eax
794
        ret
3555 Serge 795
 
3626 Serge 796
  .packets_tx:
797
        mov     eax, [eax + NET_DEVICE.packets_tx]
798
        mov     [esp+32], eax
799
        ret
3555 Serge 800
 
3626 Serge 801
  .packets_rx:
802
        mov     eax, [eax + NET_DEVICE.packets_rx]
803
        mov     [esp+32], eax
804
        ret
3555 Serge 805
 
3626 Serge 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
3555 Serge 812
 
3626 Serge 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
3555 Serge 819
 
3626 Serge 820
  .state:
821
        mov     eax, [eax + NET_DEVICE.link_state]
3555 Serge 822
        mov     [esp+32], eax
2434 Serge 823
        ret
1 ha 824
 
825
 
3626 Serge 826
  .doesnt_exist:
827
        mov     dword[esp+32], -1
828
        ret
829
 
830
 
831
 
3555 Serge 832
;----------------------------------------------------------------
1 ha 833
;
3555 Serge 834
;  System function to work with protocols  (76)
1 ha 835
;
3555 Serge 836
;----------------------------------------------------------------
837
align 4
838
sys_protocols:
3626 Serge 839
        cmp     bh, NET_DEVICES_MAX             ; Check if device number exists
3555 Serge 840
        jae     .doesnt_exist
1 ha 841
 
3555 Serge 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
1 ha 847
 
3555 Serge 848
        push    .return                         ; return address (we will be using jumps instead of calls)
1 ha 849
 
3555 Serge 850
        mov     eax, ebx                        ; set ax to protocol number
851
        shr     eax, 16                         ;
1 ha 852
 
3555 Serge 853
        cmp     ax, API_ETH
854
        je      ETH_api
1 ha 855
 
3555 Serge 856
        cmp     ax, API_IPv4
857
        je      IPv4_api
1 ha 858
 
3555 Serge 859
        cmp     ax, API_ICMP
860
        je      ICMP_api
1 ha 861
 
3555 Serge 862
        cmp     ax, API_UDP
863
        je      UDP_api
1 ha 864
 
3555 Serge 865
        cmp     ax, API_TCP
866
        je      TCP_api
1 ha 867
 
3555 Serge 868
        cmp     ax, API_ARP
869
        je      ARP_api
1 ha 870
 
3555 Serge 871
        cmp     ax, API_PPPOE
872
        je      PPPoE_api
1 ha 873
 
3555 Serge 874
        cmp     ax, API_IPv6
875
        je      IPv6_api
1 ha 876
 
3555 Serge 877
        add     esp, 4                           ; if we reached here, no function was called, so we need to balance stack
1 ha 878
 
3555 Serge 879
  .doesnt_exist:
880
        mov     eax, -1
1 ha 881
 
3555 Serge 882
  .return:
883
        mov     [esp+28+4], eax                 ; return eax value to the program
2434 Serge 884
        ret