Subversion Repositories Kolibri OS

Rev

Rev 5984 | 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: 6078 $
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
6078 serge 166
NET_BUFF_LOOPBACK       = 0
167
NET_BUFF_ETH            = 1
5565 serge 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
 
6078 serge 261
;-----------------------------------------------------------------;
262
;                                                                 ;
263
; stack_init: Initialize all network variables                    ;
264
;                                                                 ;
265
;  IN:  /                                                         ;
266
;  OUT: /                                                         ;
267
;                                                                 ;
268
;-----------------------------------------------------------------;
1168 Lrz 269
align 4
3555 Serge 270
stack_init:
1 ha 271
 
5565 serge 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
 
3555 Serge 289
; Init the network drivers list
290
        xor     eax, eax
291
        mov     edi, NET_RUNNING
5565 serge 292
        mov     ecx, (NET_DEVICES_MAX + 1)
3725 Serge 293
        rep stosd
1 ha 294
 
6078 serge 295
        eth_init
4265 Serge 296
 
6078 serge 297
        pppoe_init
1 ha 298
 
6078 serge 299
        ipv4_init
300
;        ipv6_init
301
        icmp_init
1 ha 302
 
6078 serge 303
        arp_init
304
        udp_init
305
        tcp_init
1 ha 306
 
6078 serge 307
        socket_init
1 ha 308
 
6078 serge 309
        loop_init
3626 Serge 310
 
3555 Serge 311
        mov     [net_tmr_count], 0
5565 serge 312
        ret
1 ha 313
 
5565 serge 314
  .fail:
315
        DEBUGF  DEBUG_NETWORK_ERROR, "Stack init failed!\n"
2434 Serge 316
        ret
1 ha 317
 
318
 
319
 
3555 Serge 320
; Wakeup every tick.
321
proc stack_handler_has_work?
1 ha 322
 
3725 Serge 323
        mov     eax, [timer_ticks]
324
        cmp     eax, [net_10ms]
1 ha 325
 
2434 Serge 326
        ret
261 hidnplayr 327
endp
1 ha 328
 
3555 Serge 329
 
6078 serge 330
;-----------------------------------------------------------------;
331
;                                                                 ;
332
; stack_handler: Network handlers called from os_loop.            ;
333
;                                                                 ;
334
;  IN:  /                                                         ;
335
;  OUT: /                                                         ;
336
;                                                                 ;
337
;-----------------------------------------------------------------;
3555 Serge 338
align 4
339
stack_handler:
261 hidnplayr 340
 
3555 Serge 341
        ; Test for 10ms tick
342
        mov     eax, [timer_ticks]
343
        cmp     eax, [net_10ms]
344
        je      .exit
345
        mov     [net_10ms], eax
261 hidnplayr 346
 
3555 Serge 347
        cmp     [NET_RUNNING], 0
348
        je      .exit
1 ha 349
 
3555 Serge 350
        test    [net_10ms], 0x0f        ; 160ms
351
        jnz     .exit
1 ha 352
 
6078 serge 353
        tcp_timer_160ms
1 ha 354
 
3555 Serge 355
        test    [net_10ms], 0x3f        ; 640ms
356
        jnz     .exit
1 ha 357
 
6078 serge 358
        arp_decrease_entry_ttls
359
        ipv4_decrease_fragment_ttls
1 ha 360
 
5201 serge 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
 
3555 Serge 367
  .exit:
368
        ret
1 ha 369
 
370
 
3908 Serge 371
align 4
6078 serge 372
proc net_buff_alloc stdcall, buffersize
373
 
5565 serge 374
        cmp     [buffersize], NET_BUFFER_SIZE
375
        ja      .too_large
1 ha 376
 
5565 serge 377
        spin_lock_irqsave
3908 Serge 378
 
5565 serge 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
 
6078 serge 387
        DEBUGF  DEBUG_NETWORK_VERBOSE, "net_buff_alloc: 0x%x\n", eax
5565 serge 388
        ret
389
 
390
  .out_of_mem:
391
        spin_unlock_irqrestore
392
 
393
        xor     eax, eax
6078 serge 394
        DEBUGF  DEBUG_NETWORK_ERROR, "net_buff_alloc: out of mem!\n"
5565 serge 395
        ret
396
 
397
  .too_large:
398
        xor     eax, eax
6078 serge 399
        DEBUGF  DEBUG_NETWORK_ERROR, "net_buff_alloc: too large!\n"
5565 serge 400
        ret
401
endp
402
 
403
 
3555 Serge 404
align 4
6078 serge 405
proc net_buff_free stdcall, buffer
5565 serge 406
 
6078 serge 407
        DEBUGF  DEBUG_NETWORK_VERBOSE, "net_buff_free: 0x%x\n", [buffer]
5565 serge 408
 
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
 
422
align 4
6078 serge 423
net_link_changed:
323 hidnplayr 424
 
6078 serge 425
        DEBUGF  DEBUG_NETWORK_VERBOSE, "net_link_changed device=0x%x status=0x%x\n", ebx, [ebx + NET_DEVICE.link_state]
1 ha 426
 
3555 Serge 427
align 4
6078 serge 428
net_send_event:
1 ha 429
 
6078 serge 430
        DEBUGF  DEBUG_NETWORK_VERBOSE, "net_send_event\n"
1 ha 431
 
3555 Serge 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
1 ha 441
 
3555 Serge 442
        ret
1 ha 443
 
444
 
445
 
6078 serge 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
;-----------------------------------------------------------------;
3555 Serge 456
align 4
6078 serge 457
net_add_device:
1 ha 458
 
6078 serge 459
        DEBUGF  DEBUG_NETWORK_VERBOSE, "net_add_device: %x\n", ebx   ;;; TODO: use mutex to lock net device list
1 ha 460
 
3626 Serge 461
        cmp     [NET_RUNNING], NET_DEVICES_MAX
3555 Serge 462
        jae     .error
1 ha 463
 
3555 Serge 464
;----------------------------------
465
; Check if device is already listed
466
        mov     eax, ebx
3626 Serge 467
        mov     ecx, NET_DEVICES_MAX    ; We need to check whole list because a device may be removed without re-organizing list
3555 Serge 468
        mov     edi, NET_DRV_LIST
1 ha 469
 
3725 Serge 470
        repne scasd                     ; See if device is already in the list
3555 Serge 471
        jz      .error
1 ha 472
 
3555 Serge 473
;----------------------------
474
; Find empty slot in the list
475
        xor     eax, eax
3626 Serge 476
        mov     ecx, NET_DEVICES_MAX
3555 Serge 477
        mov     edi, NET_DRV_LIST
1 ha 478
 
3725 Serge 479
        repne scasd
3555 Serge 480
        jnz     .error
1 ha 481
 
3555 Serge 482
        sub     edi, 4
1 ha 483
 
3555 Serge 484
;-----------------------------
485
; Add device to the found slot
486
        mov     [edi], ebx              ; add device to list
1 ha 487
 
3555 Serge 488
        mov     eax, edi                ; Calculate device number in eax
489
        sub     eax, NET_DRV_LIST
490
        shr     eax, 2
1 ha 491
 
3555 Serge 492
        inc     [NET_RUNNING]           ; Indicate that one more network device is up and running
1 ha 493
 
6078 serge 494
        call    net_send_event
1 ha 495
 
3589 Serge 496
        DEBUGF  DEBUG_NETWORK_VERBOSE, "Device number: %u\n", eax
2434 Serge 497
        ret
1 ha 498
 
3555 Serge 499
  .error:
500
        or      eax, -1
3589 Serge 501
        DEBUGF  DEBUG_NETWORK_ERROR, "Adding network device failed\n"
2434 Serge 502
        ret
261 hidnplayr 503
 
1 ha 504
 
505
 
6078 serge 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
;-----------------------------------------------------------------;
3555 Serge 515
align 4
6078 serge 516
net_remove_device:
379 serge 517
 
3555 Serge 518
        cmp     [NET_RUNNING], 0
519
        je      .error
261 hidnplayr 520
 
3555 Serge 521
;----------------------------
522
; Find the driver in the list
379 serge 523
 
3555 Serge 524
        mov     eax, ebx
3626 Serge 525
        mov     ecx, NET_DEVICES_MAX
526
        mov     edi, NET_DRV_LIST
261 hidnplayr 527
 
3725 Serge 528
        repne scasd
3555 Serge 529
        jnz     .error
379 serge 530
 
3555 Serge 531
;------------------------
532
; Remove it from the list
379 serge 533
 
3555 Serge 534
        xor     eax, eax
535
        mov     dword [edi-4], eax
3626 Serge 536
        dec     [NET_RUNNING]
3555 Serge 537
 
6078 serge 538
        call    net_send_event
3555 Serge 539
 
3626 Serge 540
        xor     eax, eax
1369 Lrz 541
        ret
379 serge 542
 
3555 Serge 543
  .error:
544
        or      eax, -1
1369 Lrz 545
        ret
379 serge 546
 
261 hidnplayr 547
 
1 ha 548
 
6078 serge 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
;-----------------------------------------------------------------;
1369 Lrz 559
align 4
6078 serge 560
net_ptr_to_num:
3725 Serge 561
 
6078 serge 562
        call    net_ptr_to_num4
3725 Serge 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
6078 serge 569
net_ptr_to_num4:                ; Todo, place number in device structure so we only need to verify?
3725 Serge 570
 
5565 serge 571
        test    ebx, ebx
572
        jz      .fail
573
 
3555 Serge 574
        push    ecx
3626 Serge 575
        mov     ecx, NET_DEVICES_MAX
3555 Serge 576
        mov     edi, NET_DRV_LIST
577
  .loop:
578
        cmp     ebx, [edi]
3725 Serge 579
        je      .found
3555 Serge 580
        add     edi, 4
581
        dec     ecx
582
        jnz     .loop
1 ha 583
 
5565 serge 584
        pop     ecx
585
  .fail:
3555 Serge 586
        or      edi, -1
2434 Serge 587
        ret
1 ha 588
 
3555 Serge 589
  .found:
590
        sub     edi, NET_DRV_LIST
591
        pop     ecx
2434 Serge 592
        ret
1 ha 593
 
6078 serge 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
;-----------------------------------------------------------------;
3555 Serge 605
align 4
606
checksum_1:
1369 Lrz 607
 
3555 Serge 608
        shr     ecx, 1
609
        pushf
610
        jz      .no_2
1369 Lrz 611
 
3555 Serge 612
        shr     ecx, 1
613
        pushf
614
        jz      .no_4
1369 Lrz 615
 
3555 Serge 616
        shr     ecx, 1
617
        pushf
618
        jz      .no_8
1369 Lrz 619
 
3555 Serge 620
  .loop:
621
        add     dl, [esi+1]
622
        adc     dh, [esi+0]
1 ha 623
 
3555 Serge 624
        adc     dl, [esi+3]
625
        adc     dh, [esi+2]
1 ha 626
 
3555 Serge 627
        adc     dl, [esi+5]
628
        adc     dh, [esi+4]
1 ha 629
 
3555 Serge 630
        adc     dl, [esi+7]
631
        adc     dh, [esi+6]
1 ha 632
 
3555 Serge 633
        adc     edx, 0
634
        add     esi, 8
1 ha 635
 
3555 Serge 636
        dec     ecx
637
        jnz     .loop
1 ha 638
 
3555 Serge 639
        adc     edx, 0
1 ha 640
 
3555 Serge 641
  .no_8:
642
        popf
643
        jnc     .no_4
1 ha 644
 
3555 Serge 645
        add     dl, [esi+1]
646
        adc     dh, [esi+0]
1 ha 647
 
3555 Serge 648
        adc     dl, [esi+3]
649
        adc     dh, [esi+2]
1 ha 650
 
3555 Serge 651
        adc     edx, 0
652
        add     esi, 4
1 ha 653
 
3555 Serge 654
  .no_4:
655
        popf
656
        jnc     .no_2
1 ha 657
 
3555 Serge 658
        add     dl, [esi+1]
659
        adc     dh, [esi+0]
1 ha 660
 
3555 Serge 661
        adc     edx, 0
662
        inc     esi
663
        inc     esi
1 ha 664
 
3555 Serge 665
  .no_2:
666
        popf
667
        jnc     .end
1 ha 668
 
3555 Serge 669
        add     dh, [esi+0]
670
        adc     edx, 0
671
  .end:
2434 Serge 672
        ret
1 ha 673
 
6078 serge 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
;-----------------------------------------------------------------;
3555 Serge 683
align 4
684
checksum_2:
1 ha 685
 
3555 Serge 686
        mov     ecx, edx
687
        shr     ecx, 16
688
        and     edx, 0xffff
689
        add     edx, ecx
1 ha 690
 
3555 Serge 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
1 ha 700
 
3589 Serge 701
        DEBUGF  DEBUG_NETWORK_VERBOSE, "Checksum: %x\n", dx
3555 Serge 702
 
2434 Serge 703
        ret
1 ha 704
 
705
 
706
 
6078 serge 707
;-----------------------------------------------------------------;
708
;                                                                 ;
709
;  System function 74: Low level access to network devices.       ;
710
;                                                                 ;
711
;-----------------------------------------------------------------;
3555 Serge 712
align 4
3626 Serge 713
sys_network:
1 ha 714
 
3908 Serge 715
        cmp     bl, 255
3555 Serge 716
        jne     @f
1 ha 717
 
3555 Serge 718
        mov     eax, [NET_RUNNING]
3626 Serge 719
        mov     [esp+32], eax
720
        ret
1 ha 721
 
3555 Serge 722
   @@:
3626 Serge 723
        cmp     bh, NET_DEVICES_MAX             ; Check if device number exists
3555 Serge 724
        jae     .doesnt_exist
1 ha 725
 
3555 Serge 726
        mov     esi, ebx
727
        and     esi, 0x0000ff00
728
        shr     esi, 6
1 ha 729
 
6078 serge 730
        cmp     dword[esi + NET_DRV_LIST], 0    ; check if driver is running
3555 Serge 731
        je      .doesnt_exist
1 ha 732
 
3555 Serge 733
        mov     eax, [esi + NET_DRV_LIST]
1 ha 734
 
3555 Serge 735
        and     ebx, 0x000000ff
736
        cmp     ebx, .number
737
        ja      .doesnt_exist
738
        jmp     dword [.table + 4*ebx]
1 ha 739
 
3555 Serge 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
3626 Serge 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
3555 Serge 753
  .number = ($ - .table) / 4 - 1
1 ha 754
 
3626 Serge 755
  .get_type:
756
        mov     eax, [eax + NET_DEVICE.device_type]
757
        mov     [esp+32], eax
758
        ret
1 ha 759
 
3626 Serge 760
  .get_dev_name:
3555 Serge 761
        mov     esi, [eax + NET_DEVICE.name]
762
        mov     edi, ecx
1 ha 763
 
3555 Serge 764
        mov     ecx, 64/4 ; max length
3725 Serge 765
        rep movsd
3555 Serge 766
 
2434 Serge 767
        xor     eax, eax
3626 Serge 768
        mov     [esp+32], eax
769
        ret
1 ha 770
 
3626 Serge 771
  .reset:
3555 Serge 772
        call    [eax + NET_DEVICE.reset]
3626 Serge 773
        mov     [esp+32], eax
774
        ret
1 ha 775
 
3626 Serge 776
  .stop:
3555 Serge 777
        call    [eax + NET_DEVICE.unload]
3626 Serge 778
        mov     [esp+32], eax
779
        ret
1 ha 780
 
781
 
3626 Serge 782
  .get_ptr:
783
        mov     [esp+32], eax
784
        ret
1 ha 785
 
786
 
3626 Serge 787
  .get_drv_name:
2434 Serge 788
        xor     eax, eax
3626 Serge 789
        mov     [esp+32], eax
790
        ret
3555 Serge 791
 
3626 Serge 792
  .packets_tx:
793
        mov     eax, [eax + NET_DEVICE.packets_tx]
794
        mov     [esp+32], eax
795
        ret
3555 Serge 796
 
3626 Serge 797
  .packets_rx:
798
        mov     eax, [eax + NET_DEVICE.packets_rx]
799
        mov     [esp+32], eax
800
        ret
3555 Serge 801
 
3626 Serge 802
  .bytes_tx:
6078 serge 803
        mov     ebx, dword[eax + NET_DEVICE.bytes_tx + 4]
3626 Serge 804
        mov     [esp+20], ebx
6078 serge 805
        mov     eax, dword[eax + NET_DEVICE.bytes_tx]
3626 Serge 806
        mov     [esp+32], eax
807
        ret
3555 Serge 808
 
3626 Serge 809
  .bytes_rx:
6078 serge 810
        mov     ebx, dword[eax + NET_DEVICE.bytes_rx + 4]
3626 Serge 811
        mov     [esp+20], ebx
6078 serge 812
        mov     eax, dword[eax + NET_DEVICE.bytes_rx]
3626 Serge 813
        mov     [esp+32], eax
814
        ret
3555 Serge 815
 
3626 Serge 816
  .state:
817
        mov     eax, [eax + NET_DEVICE.link_state]
3555 Serge 818
        mov     [esp+32], eax
2434 Serge 819
        ret
1 ha 820
 
821
 
3626 Serge 822
  .doesnt_exist:
823
        mov     dword[esp+32], -1
824
        ret
825
 
826
 
827
 
6078 serge 828
;-----------------------------------------------------------------;
829
;                                                                 ;
830
;  System function 76: Low level access to protocol handlers.     ;
831
;                                                                 ;
832
;-----------------------------------------------------------------;
3555 Serge 833
align 4
834
sys_protocols:
3626 Serge 835
        cmp     bh, NET_DEVICES_MAX             ; Check if device number exists
3555 Serge 836
        jae     .doesnt_exist
1 ha 837
 
3555 Serge 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
1 ha 843
 
3555 Serge 844
        push    .return                         ; return address (we will be using jumps instead of calls)
1 ha 845
 
3555 Serge 846
        mov     eax, ebx                        ; set ax to protocol number
847
        shr     eax, 16                         ;
1 ha 848
 
3555 Serge 849
        cmp     ax, API_ETH
6078 serge 850
        je      eth_api
1 ha 851
 
3555 Serge 852
        cmp     ax, API_IPv4
6078 serge 853
        je      ipv4_api
1 ha 854
 
3555 Serge 855
        cmp     ax, API_ICMP
6078 serge 856
        je      icmp_api
1 ha 857
 
3555 Serge 858
        cmp     ax, API_UDP
6078 serge 859
        je      udp_api
1 ha 860
 
3555 Serge 861
        cmp     ax, API_TCP
6078 serge 862
        je      tcp_api
1 ha 863
 
3555 Serge 864
        cmp     ax, API_ARP
6078 serge 865
        je      arp_api
1 ha 866
 
3555 Serge 867
        cmp     ax, API_PPPOE
6078 serge 868
        je      pppoe_api
1 ha 869
 
3555 Serge 870
        cmp     ax, API_IPv6
6078 serge 871
        je      ipv6_api
1 ha 872
 
3555 Serge 873
        add     esp, 4                           ; if we reached here, no function was called, so we need to balance stack
1 ha 874
 
3555 Serge 875
  .doesnt_exist:
876
        mov     eax, -1
1 ha 877
 
3555 Serge 878
  .return:
879
        mov     [esp+28+4], eax                 ; return eax value to the program
2434 Serge 880
        ret