Subversion Repositories Kolibri OS

Rev

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