Subversion Repositories Kolibri OS

Rev

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

Rev Author Line No. Line
2288 clevermous 1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2
;;                                                              ;;
2455 mario79 3
;; Copyright (C) KolibriOS team 2004-2011. All rights reserved. ;;
2288 clevermous 4
;; Distributed under terms of the GNU General Public License    ;;
5
;;                                                              ;;
6
;;  STACK.INC                                                   ;;
7
;;                                                              ;;
8
;;  TCP/IP stack for Menuet OS                                  ;;
9
;;                                                              ;;
10
;;  Copyright 2002 Mike Hibbett, mikeh@oceanfree.net            ;;
11
;;                                                              ;;
12
;;  See file COPYING for details                                ;;
13
;;                                                              ;;
14
;; Version 0.7                                                  ;;
15
;;      Added a timer per socket to allow delays when rx window ;;
16
;;      gets below 1KB                                          ;;
17
;;                                                              ;;
18
;;10.01.2007 Bugfix for checksum function from Paolo Franchetti ;;
19
;;                                                              ;;
20
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
21
 
22
$Revision: 3534 $
23
 
24
 
25
;*******************************************************************
26
;   Interface
27
;      The interfaces defined in ETHERNET.INC plus:
28
;      stack_init
29
;      stack_handler
30
;      app_stack_handler
31
;      app_socket_handler
32
;      checksum
33
;
34
;*******************************************************************
35
 
36
uglobal
37
StackCounters:
38
  dumped_rx_count     dd  0
39
  arp_tx_count:
40
                      dd  0
41
  arp_rx_count:
42
                      dd  0
43
  ip_rx_count:
44
                      dd  0
45
  ip_tx_count:
46
                      dd  0
47
endg
48
 
49
; socket buffers
50
SOCKETBUFFSIZE     equ        4096  ; state + config + buffer.
51
SOCKETHEADERSIZE   equ        SOCKET.rxData ; thus 4096 - SOCKETHEADERSIZE bytes data
52
 
53
;NUM_SOCKETS        equ        16    ; Number of open sockets supported. Was 20
54
 
55
; IPBUFF status values
56
BUFF_EMPTY         equ     0
57
BUFF_RX_FULL       equ     1
58
BUFF_ALLOCATED     equ     2
59
BUFF_TX_FULL       equ     3
60
 
61
NUM_IPBUFFERS      equ     20    ; buffers allocated for TX/RX
62
 
63
NUMQUEUES          equ        4
64
 
65
EMPTY_QUEUE        equ        0
66
IPIN_QUEUE         equ        1
67
IPOUT_QUEUE        equ        2
68
NET1OUT_QUEUE      equ        3
69
 
70
NO_BUFFER          equ        0xFFFF
71
IPBUFFSIZE         equ        1500                ; MTU of an ethernet packet
72
NUMQUEUEENTRIES    equ        NUM_IPBUFFERS
73
NUMRESENDENTRIES    equ         18              ; Buffers for TCP resend packets
74
 
75
; These are the 0x40 function codes for application access to the stack
76
STACK_DRIVER_STATUS  equ   52
77
SOCKET_INTERFACE     equ   53
78
 
79
 
80
; 128KB allocated for the stack and network driver buffers and other
81
; data requirements
82
;stack_data_start     equ   0x700000
83
;eth_data_start       equ   0x700000
84
;stack_data           equ   0x704000
85
;stack_data_end       equ   0x71ffff
86
 
87
; 32 bit word
88
stack_config         equ   stack_data
89
 
90
; 32 bit word - IP Address in network format
91
stack_ip             equ   stack_data + 4
92
 
93
; 1 byte. 0 == inactive, 1 = active
94
ethernet_active      equ   stack_data + 9
95
 
96
 
97
; TODO :: empty memory area
98
 
99
; Address of selected socket
100
;sktAddr              equ   stack_data + 32
101
; Parameter to checksum routine - data ptr
102
checkAdd1            equ   stack_data + 36
103
; Parameter to checksum routine - 2nd data ptr
104
checkAdd2            equ   stack_data + 40
105
; Parameter to checksum routine - data size
106
checkSize1           equ   stack_data + 44
107
; Parameter to checksum routine - 2nd data size
108
checkSize2           equ   stack_data + 46
109
; result of checksum routine
110
checkResult          equ   stack_data + 48
111
 
112
; holds the TCP/UDP pseudo header. SA|DA|0|prot|UDP len|
113
pseudoHeader         equ   stack_data + 50
114
 
115
; receive and transmit IP buffer allocation
116
;sockets              equ   stack_data + 62
117
Next_free2 equ stack_data + 62;Next_free2           equ   sockets + (SOCKETBUFFSIZE * NUM_SOCKETS)
118
; 1560 byte buffer for rx / tx ethernet packets
119
Ether_buffer         equ   Next_free2
120
Next_free3           equ   Ether_buffer + 1518
121
last_1sTick          equ   Next_free3
122
IPbuffs              equ   Next_free3 + 1
123
queues               equ   IPbuffs + ( NUM_IPBUFFERS * IPBUFFSIZE )
124
queueList            equ   queues + (2 * NUMQUEUES)
125
last_1hsTick         equ   queueList + ( 2 * NUMQUEUEENTRIES )
126
 
127
;resendQ              equ   queueList + ( 2 * NUMQUEUEENTRIES )
128
;resendBuffer         equ    resendQ + ( 4 * NUMRESENDENTRIES ) ; for TCP
129
;                    equ    resendBuffer + ( IPBUFFSIZE * NUMRESENDENTRIES )
130
 
131
 
132
 
133
;resendQ             equ     0x770000
134
;resendBuffer        equ     resendQ + ( 4 * NUMRESENDENTRIES ) ; for TCP        ; XTODO: validate size
135
resendBuffer        equ     resendQ + ( 8 * NUMRESENDENTRIES ) ; for TCP
136
 
137
 
138
uglobal
139
net_sockets rd 2
140
endg
141
 
142
; simple macro for memory set operation
143
macro _memset_dw adr,value,amount
144
{
145
        mov     edi, adr
146
        mov     ecx, amount
147
        if value = 0
148
        xor     eax, eax
149
        else
150
        mov     eax, value
151
        end if
152
        cld
153
        rep stosd
154
}
155
 
156
 
157
; Below, the main network layer source code is included
158
;
159
include "queue.inc"
160
include "eth_drv/ethernet.inc"
161
include "ip.inc"
162
include "socket.inc"
163
 
164
;***************************************************************************
165
;   Function
166
;      stack_init
167
;
168
;   Description
169
;      Clear all allocated memory to zero. This ensures that
170
;       on startup, the stack is inactive, and consumes no resources
171
;       This is a kernel function, called prior to the OS main loop
172
;       in set_variables
173
;
174
;***************************************************************************
175
 
176
stack_init:
177
        ; Init two address spaces with default values
178
        _memset_dw      stack_data_start, 0, 0x20000/4
179
        _memset_dw      resendQ, 0, NUMRESENDENTRIES * 2
180
 
181
        mov     [net_sockets], 0
182
        mov     [net_sockets + 4], 0
183
 
184
        ; Queries initialization
185
        call    queueInit
186
 
187
        ; The following block sets up the 1s timer
188
        mov     al, 0x0
189
        out     0x70, al
190
        in      al, 0x71
191
        mov     [last_1sTick], al
192
        ret
193
 
3534 clevermous 194
; Wakeup every tick.
195
proc stack_handler_has_work?
196
        mov     eax, [timer_ticks]
197
        cmp     eax, [last_1hsTick]
198
        ret
199
endp
2288 clevermous 200
 
201
 
202
;***************************************************************************
203
;   Function
204
;      stack_handler
205
;
206
;   Description
207
;       The kernel loop routine for the stack
208
;       This is a kernel function, called in the main loop
209
;
210
;***************************************************************************
211
align 4
212
stack_handler:
213
 
214
        call    ethernet_driver
215
        call    ip_rx
216
 
217
 
218
    ; Test for 10ms tick, call tcp timer
219
        mov     eax, [timer_ticks];[0xfdf0]
220
        cmp     eax, [last_1hsTick]
221
        je      sh_001
222
 
223
        mov     [last_1hsTick], eax
224
        call    tcp_tx_handler
225
 
226
sh_001:
227
 
228
    ; Test for 1 second event, call 1s timer functions
229
        mov     al, 0x0;second
230
        out     0x70, al
231
        in      al, 0x71
232
        cmp     al, [last_1sTick]
233
        je      sh_exit
234
 
235
        mov     [last_1sTick], al
236
 
237
        stdcall arp_table_manager, ARP_TABLE_TIMER, 0, 0
238
        call    tcp_tcb_handler
239
 
240
sh_exit:
241
        ret
242
 
243
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
244
;; Checksum [by Johnny_B]
245
;;  IN:
246
;;    buf_ptr=POINTER to buffer
247
;;    buf_size=SIZE of buffer
248
;;  OUT:
249
;;    AX=16-bit checksum
250
;;              Saves all used registers
251
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
252
proc checksum_jb stdcall uses ebx esi ecx,\
253
     buf_ptr:DWORD, buf_size:DWORD
254
 
255
        xor     eax, eax
256
        xor     ebx, ebx;accumulator
257
        mov     esi, dword[buf_ptr]
258
        mov     ecx, dword[buf_size]
259
        shr     ecx, 1; ecx=ecx/2
260
        jnc     @f  ; if CF==0 then size is even number
261
        mov     bh, byte[esi + ecx*2]
262
  @@:
263
        cld
264
 
265
  .loop:
266
        lodsw   ;eax=word[esi],esi=esi+2
267
        xchg    ah, al;cause must be a net byte-order
268
        add     ebx, eax
269
        loop    .loop
270
 
271
        mov     eax, ebx
272
        shr     eax, 16
273
        add     ax, bx
274
        not     ax
275
 
276
        ret
277
endp
278
 
279
;***************************************************************************
280
;   Function
281
;      checksum
282
;
283
;   Description
284
;       checkAdd1,checkAdd2, checkSize1, checkSize2, checkResult
285
;       Dont break anything; Most registers are used by the caller
286
;       This code is derived from the 'C' source, cksum.c, in the book
287
;       Internetworking with TCP/IP Volume II by D.E. Comer
288
;
289
;***************************************************************************
290
 
291
 
292
checksum:
293
        pusha
294
        mov     eax, [checkAdd1]
295
        xor     edx, edx              ; edx is the accumulative checksum
296
        xor     ebx, ebx
297
        mov     cx, [checkSize1]
298
        shr     cx, 1
299
        jz      cs1_1
300
 
301
cs1:
302
        mov     bh, [eax]
303
        mov     bl, [eax + 1]
304
 
305
        add     eax, 2
306
        add     edx, ebx
307
 
308
        loopw   cs1
309
 
310
cs1_1:
311
        and     word [checkSize1], 0x01
312
        jz      cs_test2
313
 
314
        mov     bh, [eax]
315
        xor     bl, bl
316
 
317
        add     edx, ebx
318
 
319
cs_test2:
320
        mov     cx, [checkSize2]
321
        cmp     cx, 0
322
        jz      cs_exit                 ; Finished if no 2nd buffer
323
 
324
        mov     eax, [checkAdd2]
325
 
326
        shr     cx, 1
327
        jz      cs2_1
328
 
329
cs2:
330
        mov     bh, [eax]
331
        mov     bl, [eax + 1]
332
 
333
        add     eax, 2
334
        add     edx, ebx
335
 
336
        loopw   cs2
337
 
338
cs2_1:
339
        and     word [checkSize2], 0x01
340
        jz      cs_exit
341
 
342
        mov     bh, [eax]
343
        xor     bl, bl
344
 
345
        add     edx, ebx
346
 
347
cs_exit:
348
        mov     ebx, edx
349
 
350
        shr     ebx, 16
351
        and     edx, 0xffff
352
        add     edx, ebx
353
        mov     eax, edx
354
        shr     eax, 16
355
        add     edx, eax
356
        not     dx
357
 
358
        mov     [checkResult], dx
359
        popa
360
        ret
361
 
362
 
363
 
364
 
365
;***************************************************************************
366
;   Function
367
;      app_stack_handler
368
;
369
;   Description
370
;       This is an application service, called by int 0x40, function 52
371
;       It provides application access to the network interface layer
372
;
373
;***************************************************************************
374
iglobal
375
align 4
376
f52call:
377
        dd      app_stack_handler.00
378
        dd      app_stack_handler.01
379
        dd      app_stack_handler.02
380
        dd      app_stack_handler.03
381
        dd      app_stack_handler.fail  ;04
382
        dd      app_stack_handler.fail  ;05
383
        dd      stack_insert_packet     ;app_stack_handler.06
384
        dd      app_stack_handler.fail  ;07
385
        dd      stack_get_packet        ;app_stack_handler.08
386
        dd      app_stack_handler.09
387
        dd      app_stack_handler.10
388
        dd      app_stack_handler.11
389
        dd      app_stack_handler.12
390
        dd      app_stack_handler.13
391
        dd      app_stack_handler.14
392
        dd      app_stack_handler.15
393
endg
394
app_stack_handler:
395
;in ebx,ecx
396
;out eax
397
        cmp     ebx, 15
398
        ja      .fail                   ;if more than 15 then exit
399
 
400
        jmp     dword [f52call+ebx*4]
401
 
402
 
403
.00:
404
; Read the configuration word
405
        mov     eax, [stack_config]
406
        ret
407
 
408
.01:
409
; read the IP address
410
        mov     eax, [stack_ip]
411
        ret
412
 
413
.02:
414
; write the configuration word
415
        mov     [stack_config], ecx
416
 
417
; 
418
; If ethernet now enabled, probe for the card, reset it and empty
419
; the packet buffer
420
; If all successfull, enable the card.
421
; If ethernet now disabled, set it as disabled. Should really
422
; empty the tcpip data area too.
423
 
424
; ethernet interface is '3' in ls 7 bits
425
        and     cl, 0x7f
426
        cmp     cl, 3
427
        je      ash_eth_enable
428
; Ethernet isn't enabled, so make sure that the card is disabled
429
        mov     [ethernet_active], byte 0
430
        ret
431
 
432
.03:
433
; write the IP Address
434
        mov     [stack_ip], ecx
435
        ret
436
;old functions was deleted
437
;.06:
438
; Insert an IP packet into the stacks received packet queue
439
;       call    stack_insert_packet
440
;       ret
441
 
442
; Test for any packets queued for transmission over the network
443
 
444
;.08:
445
;       call    stack_get_packet
446
; Extract a packet queued for transmission by the network
447
;       ret
448
 
449
.09:
450
; read the gateway IP address
451
        mov     eax, [gateway_ip]
452
        ret
453
 
454
.10:
455
; read the subnet mask
456
        mov     eax, [subnet_mask]
457
        ret
458
.11:
459
; write the gateway IP Address
460
        mov     [gateway_ip], ecx
461
        ret
462
 
463
.12:
464
; write the subnet mask
465
        mov     [subnet_mask], ecx
466
        ret
467
 
468
.13:
469
; read the dns
470
        mov     eax, [dns_ip]
471
        ret
472
 
473
.14:
474
; write the dns IP Address
475
        mov     [dns_ip], ecx
476
        ret
477
 
478
.15:
479
;
480
; in ecx we need 4 to read the last 2 bytes
481
; or we need 0 to read the first 4 bytes
482
        cmp     ecx, 4
483
        ja      .param_error
484
 
485
; read MAC, returned (in mirrored byte order) in eax
486
        mov     eax, [node_addr + ecx]
487
        ret
488
 
489
.param_error:
490
        or      eax, -1         ; params not accepted
491
        ret
492
 
493
.16:
494
; 0 -> arp_probe
495
; 1 -> arp_announce
496
; 2 -> arp_responce (not supported yet)
497
        test    ecx, ecx
498
        je      a_probe
499
 
500
        dec     ebx
501
        jz      a_ann                   ; arp announce
502
.fail:
503
        or      eax, -1
504
        ret
505
 
506
;       cmp     ebx,2
507
;       jne     a_resp                  ; arp response
508
 
509
; arp probe, sender IP must be set to 0.0.0.0, target IP is set to address being probed
510
; ecx: pointer to target MAC, MAC should set to 0 by application
511
; edx: target IP
512
a_probe:
513
        push    dword [stack_ip]
514
 
515
        mov     edx, [stack_ip]
516
        and     [stack_ip], dword 0
517
        mov     esi, ecx                ; pointer to target MAC address
518
        call    arp_request
519
 
520
        pop     dword [stack_ip]
521
        ret
522
 
523
; arp announce, sender IP must be set to target IP
524
; ecx: pointer to target MAC
525
a_ann:
526
        mov     edx, [stack_ip]
527
        mov     esi, ecx                ; pointer to target MAC address
528
        call    arp_request
529
        ret
530
 
531
.17:
532
;
533
; modified by [smb]
534
 
535
;
536
; ARPTable manager interface
537
    ;see "proc arp_table_manager" for more details
538
        stdcall arp_table_manager, ecx, edx, esi;Opcode,Index,Extra
539
        ret
540
;
541
 
542
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
543
ash_eth_enable:
544
; Probe for the card. This will reset it and enable the interface
545
; if found
546
        call    eth_probe
547
        test    eax, eax
548
        jz      ash_eth_done            ; Abort if no hardware found
549
 
550
        mov     [ethernet_active], byte 1
551
ash_eth_done:
552
        ret
553
;***************************************************************************
554
;   Function
555
;      app_socket_handler
556
;
557
;   Description
558
;       This is an application service, called by int 0x40, function 53
559
;       It provides application access to stack socket services
560
;       such as opening sockets
561
;
562
;***************************************************************************
563
iglobal
564
align 4
565
f53call:
566
        dd      socket_open                     ;00
567
        dd      socket_close                    ;01
568
        dd      socket_poll                     ;02
569
        dd      socket_read                     ;03
570
        dd      socket_write                    ;04
571
        dd      socket_open_tcp                 ;05
572
        dd      socket_status                   ;06
573
        dd      socket_write_tcp                ;07
574
        dd      socket_close_tcp                ;08
575
        dd      is_localport_unused             ;09
576
        dd      app_socket_handler.10
577
        dd      socket_read_packet              ;11
578
endg
579
 
580
app_socket_handler:
581
;in ebx,ecx,edx,wsi
582
;out eax
583
        cmp     eax, 255
584
        je      stack_internal_status
585
 
586
        cmp     eax, 11
587
        ja      .fail                   ;if more than 15 then exit
588
 
589
        jmp     dword [f53call+eax*4]
590
 
591
.10:
592
        mov     eax, dword[drvr_cable]
593
        test    eax, eax
594
        jnz     @f                      ; if function is not implented, return -1
595
        or      al, -1
596
        ret
597
@@:
598
        jmp     dword[drvr_cable]
599
 
600
.fail:
601
        or      eax, -1
602
        ret
603
uglobal
604
  ARPTmp:
605
  times 14 db 0
606
endg
607
 
608
;***************************************************************************
609
;   Function
610
;      stack_internal_status
611
;
612
;   Description
613
;       Returns information about the internal status of the stack
614
;       This is only useful for debugging
615
;       It works with the ethernet driver
616
;       sub function in ebx
617
;       return requested data in eax
618
;
619
;***************************************************************************
620
; This sub function allows access to debugging information on the stack
621
; ecx holds the request:
622
; 100 : return length of empty queue
623
; 101 : return length of IPOUT QUEUE
624
; 102 : return length of IPIN QUEUE
625
; 103 : return length of NET1OUT QUEUE
626
; 200 : return # of ARP entries
627
; 201 : return size of ARP table ( max # entries )
628
; 202 : select ARP table entry #
629
; 203 : return IP of selected table entry
630
; 204 : return High 4 bytes of MAC address of selected table entry
631
; 205 : return low  2 bytes of MAC address of selected table entry
632
; 206 : return status word of selected table entry
633
; 207 : return Time to live of selected table entry
634
 
635
 
636
;  2 : return number of IP packets received
637
;  3 : return number of packets transmitted
638
;  4 : return number of received packets dumped
639
;  5 : return number of arp packets received
640
;  6 : return status of packet driver
641
;  ( 0 == not active, FFFFFFFF = successful )
642
 
643
 
644
stack_internal_status:
645
        cmp     ebx, 100
646
        jnz     notsis100
647
 
648
    ;  100 : return length of EMPTY QUEUE
649
        mov     ebx, EMPTY_QUEUE
650
        call    queueSize
651
        ret
652
 
653
notsis100:
654
        cmp     ebx, 101
655
        jnz     notsis101
656
 
657
    ;  101 : return length of IPOUT QUEUE
658
        mov     ebx, IPOUT_QUEUE
659
        call    queueSize
660
        ret
661
 
662
notsis101:
663
        cmp     ebx, 102
664
        jnz     notsis102
665
 
666
    ;  102 : return length of IPIN QUEUE
667
        mov     ebx, IPIN_QUEUE
668
        call    queueSize
669
        ret
670
 
671
notsis102:
672
        cmp     ebx, 103
673
        jnz     notsis103
674
 
675
    ;  103 : return length of NET1OUT QUEUE
676
        mov     ebx, NET1OUT_QUEUE
677
        call    queueSize
678
        ret
679
 
680
notsis103:
681
        cmp     ebx, 200
682
        jnz     notsis200
683
 
684
    ; 200 : return num entries in arp table
685
        movzx   eax, byte [NumARP]
686
        ret
687
 
688
notsis200:
689
        cmp     ebx, 201
690
        jnz     notsis201
691
 
692
    ; 201 : return arp table size
693
        mov     eax, 20; ARP_TABLE_SIZE
694
        ret
695
 
696
notsis201:
697
        cmp     ebx, 202
698
        jnz     notsis202
699
 
700
    ; 202 - read the requested table entry
701
    ; into a temporary buffer
702
    ; ecx holds the entry number
703
 
704
        mov     eax, ecx
705
        mov     ecx, 14; ARP_ENTRY_SIZE
706
        mul     ecx
707
 
708
        mov     ecx, [eax + ARPTable]
709
        mov     [ARPTmp], ecx
710
        mov     ecx, [eax + ARPTable+4]
711
        mov     [ARPTmp+4], ecx
712
        mov     ecx, [eax + ARPTable+8]
713
        mov     [ARPTmp+8], ecx
714
        mov     cx, [eax + ARPTable+12]
715
        mov     [ARPTmp+12], cx
716
        ret
717
 
718
notsis202:
719
        cmp     ebx, 203
720
        jnz     notsis203
721
 
722
    ; 203 - return IP address
723
        mov     eax, [ARPTmp]
724
        ret
725
 
726
notsis203:
727
        cmp     ebx, 204
728
        jnz     notsis204
729
 
730
    ; 204 - return MAC high dword
731
        mov     eax, [ARPTmp+4]
732
        ret
733
 
734
notsis204:
735
        cmp     ebx, 205
736
        jnz     notsis205
737
 
738
    ; 205 - return MAC ls word
739
        movzx   eax, word [ARPTmp+8]
740
        ret
741
 
742
notsis205:
743
        cmp     ebx, 206
744
        jnz     notsis206
745
 
746
    ; 206 - return status word
747
        movzx   eax, word [ARPTmp+10]
748
        ret
749
 
750
notsis206:
751
        cmp     ebx, 207
752
        jnz     notsis207
753
 
754
    ; 207 - return ttl word
755
        movzx   eax, word [ARPTmp+12]
756
        ret
757
 
758
notsis207:
759
        cmp     ebx, 2
760
        jnz     notsis2
761
 
762
    ;  2 : return number of IP packets received
763
        mov     eax, [ip_rx_count]
764
        ret
765
 
766
notsis2:
767
        cmp     ebx, 3
768
        jnz     notsis3
769
 
770
    ;  3 : return number of packets transmitted
771
        mov     eax, [ip_tx_count]
772
        ret
773
 
774
notsis3:
775
        cmp     ebx, 4
776
        jnz     notsis4
777
 
778
    ;  4 : return number of received packets dumped
779
        mov     eax, [dumped_rx_count]
780
        ret
781
 
782
notsis4:
783
        cmp     ebx, 5
784
        jnz     notsis5
785
 
786
    ;  5 : return number of arp packets received
787
        mov     eax, [arp_rx_count]
788
        ret
789
 
790
notsis5:
791
        cmp     ebx, 6
792
        jnz     notsis6
793
 
794
    ;  6 : return status of packet driver
795
    ;  ( 0 == not active, FFFFFFFF = successful )
796
        mov     eax, [eth_status]
797
        ret
798
 
799
notsis6:
800
        xor     eax, eax
801
        ret
802
 
803
 
804
 
805
;***************************************************************************
806
;   Function
807
;      stack_get_packet
808
;
809
;   Description
810
;       extracts an IP packet from the NET1 output queue
811
;       and sends the data to the calling process
812
;       pointer to data in edx
813
;       returns number of bytes read in eax
814
;
815
;***************************************************************************
816
stack_get_packet:
817
    ; Look for a buffer to tx
818
        mov     eax, NET1OUT_QUEUE
819
        call    dequeue
820
        cmp     ax, NO_BUFFER
821
        je      sgp_non_exit        ; Exit if no buffer available
822
 
823
        push    eax                 ; Save buffer number for freeing at end
824
 
825
        push    edx
826
    ; convert buffer pointer eax to the absolute address
827
        mov     ecx, IPBUFFSIZE
828
        mul     ecx
829
        add     eax, IPbuffs
830
        pop     edx
831
 
832
        push    eax                 ; save address of IP data
833
    ; Get the address of the callers data
834
        mov     edi, [TASK_BASE]
835
        add     edi, TASKDATA.mem_start
836
        add     edx, [edi]
837
        mov     edi, edx
838
        pop     eax
839
 
840
        mov     ecx, 1500       ; should get the actual number of bytes to write
841
        mov     esi, eax
842
        cld
843
        rep movsb               ; copy the data across
844
 
845
    ; And finally, return the buffer to the free queue
846
        pop     eax
847
        call    freeBuff
848
 
849
        mov     eax, 1500
850
        ret
851
 
852
sgp_non_exit:
853
        xor     eax, eax
854
        ret
855
 
856
 
857
 
858
;***************************************************************************
859
;   Function
860
;      stack_insert_packet
861
;
862
;   Description
863
;       writes an IP packet into the stacks receive queue
864
;       # of bytes to write in ecx
865
;       pointer to data in edx
866
;       returns 0 in eax ok, -1 == failed
867
;
868
;***************************************************************************
869
stack_insert_packet:
870
 
871
        mov     eax, EMPTY_QUEUE
872
        call    dequeue
873
        cmp     ax, NO_BUFFER
874
        je      sip_err_exit
875
 
876
        push    eax
877
 
878
    ; save the pointers to the data buffer & size
879
        push    edx
880
        push    ecx
881
 
882
    ; convert buffer pointer eax to the absolute address
883
        mov     ecx, IPBUFFSIZE
884
        mul     ecx
885
        add     eax, IPbuffs
886
 
887
        mov     edx, eax
888
 
889
    ; So, edx holds the IPbuffer ptr
890
 
891
        pop     ecx                 ; count of bytes to send
892
        mov     ebx, ecx            ; need the length later
893
        pop     eax                 ; get callers ptr to data to send
894
 
895
    ; Get the address of the callers data
896
        mov     edi, [TASK_BASE]
897
        add     edi, TASKDATA.mem_start
898
        add     eax, [edi]
899
        mov     esi, eax
900
 
901
        mov     edi, edx
902
        cld
903
        rep movsb               ; copy the data across
904
 
905
        pop     ebx
906
 
907
        mov     eax, IPIN_QUEUE
908
        call    queue
909
 
910
        inc     dword [ip_rx_count]
911
 
912
        mov     eax, 0
913
        ret
914
 
915
sip_err_exit:
916
        mov     eax, 0xFFFFFFFF
917
        ret
918