Subversion Repositories Kolibri OS

Rev

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

Rev Author Line No. Line
2288 clevermous 1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2
;;                                                              ;;
3
;; Copyright (C) KolibriOS team 2004-2008. All rights reserved. ;;
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: 2288 $
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
 
194
 
195
 
196
;***************************************************************************
197
;   Function
198
;      stack_handler
199
;
200
;   Description
201
;       The kernel loop routine for the stack
202
;       This is a kernel function, called in the main loop
203
;
204
;***************************************************************************
205
align 4
206
stack_handler:
207
 
208
        call    ethernet_driver
209
        call    ip_rx
210
 
211
 
212
    ; Test for 10ms tick, call tcp timer
213
        mov     eax, [timer_ticks];[0xfdf0]
214
        cmp     eax, [last_1hsTick]
215
        je      sh_001
216
 
217
        mov     [last_1hsTick], eax
218
        call    tcp_tx_handler
219
 
220
sh_001:
221
 
222
    ; Test for 1 second event, call 1s timer functions
223
        mov     al, 0x0;second
224
        out     0x70, al
225
        in      al, 0x71
226
        cmp     al, [last_1sTick]
227
        je      sh_exit
228
 
229
        mov     [last_1sTick], al
230
 
231
        stdcall arp_table_manager, ARP_TABLE_TIMER, 0, 0
232
        call    tcp_tcb_handler
233
 
234
sh_exit:
235
        ret
236
 
237
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
238
;; Checksum [by Johnny_B]
239
;;  IN:
240
;;    buf_ptr=POINTER to buffer
241
;;    buf_size=SIZE of buffer
242
;;  OUT:
243
;;    AX=16-bit checksum
244
;;              Saves all used registers
245
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
246
proc checksum_jb stdcall uses ebx esi ecx,\
247
     buf_ptr:DWORD, buf_size:DWORD
248
 
249
        xor     eax, eax
250
        xor     ebx, ebx;accumulator
251
        mov     esi, dword[buf_ptr]
252
        mov     ecx, dword[buf_size]
253
        shr     ecx, 1; ecx=ecx/2
254
        jnc     @f  ; if CF==0 then size is even number
255
        mov     bh, byte[esi + ecx*2]
256
  @@:
257
        cld
258
 
259
  .loop:
260
        lodsw   ;eax=word[esi],esi=esi+2
261
        xchg    ah, al;cause must be a net byte-order
262
        add     ebx, eax
263
        loop    .loop
264
 
265
        mov     eax, ebx
266
        shr     eax, 16
267
        add     ax, bx
268
        not     ax
269
 
270
        ret
271
endp
272
 
273
;***************************************************************************
274
;   Function
275
;      checksum
276
;
277
;   Description
278
;       checkAdd1,checkAdd2, checkSize1, checkSize2, checkResult
279
;       Dont break anything; Most registers are used by the caller
280
;       This code is derived from the 'C' source, cksum.c, in the book
281
;       Internetworking with TCP/IP Volume II by D.E. Comer
282
;
283
;***************************************************************************
284
 
285
 
286
checksum:
287
        pusha
288
        mov     eax, [checkAdd1]
289
        xor     edx, edx              ; edx is the accumulative checksum
290
        xor     ebx, ebx
291
        mov     cx, [checkSize1]
292
        shr     cx, 1
293
        jz      cs1_1
294
 
295
cs1:
296
        mov     bh, [eax]
297
        mov     bl, [eax + 1]
298
 
299
        add     eax, 2
300
        add     edx, ebx
301
 
302
        loopw   cs1
303
 
304
cs1_1:
305
        and     word [checkSize1], 0x01
306
        jz      cs_test2
307
 
308
        mov     bh, [eax]
309
        xor     bl, bl
310
 
311
        add     edx, ebx
312
 
313
cs_test2:
314
        mov     cx, [checkSize2]
315
        cmp     cx, 0
316
        jz      cs_exit                 ; Finished if no 2nd buffer
317
 
318
        mov     eax, [checkAdd2]
319
 
320
        shr     cx, 1
321
        jz      cs2_1
322
 
323
cs2:
324
        mov     bh, [eax]
325
        mov     bl, [eax + 1]
326
 
327
        add     eax, 2
328
        add     edx, ebx
329
 
330
        loopw   cs2
331
 
332
cs2_1:
333
        and     word [checkSize2], 0x01
334
        jz      cs_exit
335
 
336
        mov     bh, [eax]
337
        xor     bl, bl
338
 
339
        add     edx, ebx
340
 
341
cs_exit:
342
        mov     ebx, edx
343
 
344
        shr     ebx, 16
345
        and     edx, 0xffff
346
        add     edx, ebx
347
        mov     eax, edx
348
        shr     eax, 16
349
        add     edx, eax
350
        not     dx
351
 
352
        mov     [checkResult], dx
353
        popa
354
        ret
355
 
356
 
357
 
358
 
359
;***************************************************************************
360
;   Function
361
;      app_stack_handler
362
;
363
;   Description
364
;       This is an application service, called by int 0x40, function 52
365
;       It provides application access to the network interface layer
366
;
367
;***************************************************************************
368
iglobal
369
align 4
370
f52call:
371
        dd      app_stack_handler.00
372
        dd      app_stack_handler.01
373
        dd      app_stack_handler.02
374
        dd      app_stack_handler.03
375
        dd      app_stack_handler.fail  ;04
376
        dd      app_stack_handler.fail  ;05
377
        dd      stack_insert_packet     ;app_stack_handler.06
378
        dd      app_stack_handler.fail  ;07
379
        dd      stack_get_packet        ;app_stack_handler.08
380
        dd      app_stack_handler.09
381
        dd      app_stack_handler.10
382
        dd      app_stack_handler.11
383
        dd      app_stack_handler.12
384
        dd      app_stack_handler.13
385
        dd      app_stack_handler.14
386
        dd      app_stack_handler.15
387
endg
388
app_stack_handler:
389
;in ebx,ecx
390
;out eax
391
        cmp     ebx, 15
392
        ja      .fail                   ;if more than 15 then exit
393
 
394
        jmp     dword [f52call+ebx*4]
395
 
396
 
397
.00:
398
; Read the configuration word
399
        mov     eax, [stack_config]
400
        ret
401
 
402
.01:
403
; read the IP address
404
        mov     eax, [stack_ip]
405
        ret
406
 
407
.02:
408
; write the configuration word
409
        mov     [stack_config], ecx
410
 
411
; 
412
; If ethernet now enabled, probe for the card, reset it and empty
413
; the packet buffer
414
; If all successfull, enable the card.
415
; If ethernet now disabled, set it as disabled. Should really
416
; empty the tcpip data area too.
417
 
418
; ethernet interface is '3' in ls 7 bits
419
        and     cl, 0x7f
420
        cmp     cl, 3
421
        je      ash_eth_enable
422
; Ethernet isn't enabled, so make sure that the card is disabled
423
        mov     [ethernet_active], byte 0
424
        ret
425
 
426
.03:
427
; write the IP Address
428
        mov     [stack_ip], ecx
429
        ret
430
;old functions was deleted
431
;.06:
432
; Insert an IP packet into the stacks received packet queue
433
;       call    stack_insert_packet
434
;       ret
435
 
436
; Test for any packets queued for transmission over the network
437
 
438
;.08:
439
;       call    stack_get_packet
440
; Extract a packet queued for transmission by the network
441
;       ret
442
 
443
.09:
444
; read the gateway IP address
445
        mov     eax, [gateway_ip]
446
        ret
447
 
448
.10:
449
; read the subnet mask
450
        mov     eax, [subnet_mask]
451
        ret
452
.11:
453
; write the gateway IP Address
454
        mov     [gateway_ip], ecx
455
        ret
456
 
457
.12:
458
; write the subnet mask
459
        mov     [subnet_mask], ecx
460
        ret
461
 
462
.13:
463
; read the dns
464
        mov     eax, [dns_ip]
465
        ret
466
 
467
.14:
468
; write the dns IP Address
469
        mov     [dns_ip], ecx
470
        ret
471
 
472
.15:
473
;
474
; in ecx we need 4 to read the last 2 bytes
475
; or we need 0 to read the first 4 bytes
476
        cmp     ecx, 4
477
        ja      .param_error
478
 
479
; read MAC, returned (in mirrored byte order) in eax
480
        mov     eax, [node_addr + ecx]
481
        ret
482
 
483
.param_error:
484
        or      eax, -1         ; params not accepted
485
        ret
486
 
487
.16:
488
; 0 -> arp_probe
489
; 1 -> arp_announce
490
; 2 -> arp_responce (not supported yet)
491
        test    ecx, ecx
492
        je      a_probe
493
 
494
        dec     ebx
495
        jz      a_ann                   ; arp announce
496
.fail:
497
        or      eax, -1
498
        ret
499
 
500
;       cmp     ebx,2
501
;       jne     a_resp                  ; arp response
502
 
503
; arp probe, sender IP must be set to 0.0.0.0, target IP is set to address being probed
504
; ecx: pointer to target MAC, MAC should set to 0 by application
505
; edx: target IP
506
a_probe:
507
        push    dword [stack_ip]
508
 
509
        mov     edx, [stack_ip]
510
        and     [stack_ip], dword 0
511
        mov     esi, ecx                ; pointer to target MAC address
512
        call    arp_request
513
 
514
        pop     dword [stack_ip]
515
        ret
516
 
517
; arp announce, sender IP must be set to target IP
518
; ecx: pointer to target MAC
519
a_ann:
520
        mov     edx, [stack_ip]
521
        mov     esi, ecx                ; pointer to target MAC address
522
        call    arp_request
523
        ret
524
 
525
.17:
526
;
527
; modified by [smb]
528
 
529
;
530
; ARPTable manager interface
531
    ;see "proc arp_table_manager" for more details
532
        stdcall arp_table_manager, ecx, edx, esi;Opcode,Index,Extra
533
        ret
534
;
535
 
536
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
537
ash_eth_enable:
538
; Probe for the card. This will reset it and enable the interface
539
; if found
540
        call    eth_probe
541
        test    eax, eax
542
        jz      ash_eth_done            ; Abort if no hardware found
543
 
544
        mov     [ethernet_active], byte 1
545
ash_eth_done:
546
        ret
547
;***************************************************************************
548
;   Function
549
;      app_socket_handler
550
;
551
;   Description
552
;       This is an application service, called by int 0x40, function 53
553
;       It provides application access to stack socket services
554
;       such as opening sockets
555
;
556
;***************************************************************************
557
iglobal
558
align 4
559
f53call:
560
        dd      socket_open                     ;00
561
        dd      socket_close                    ;01
562
        dd      socket_poll                     ;02
563
        dd      socket_read                     ;03
564
        dd      socket_write                    ;04
565
        dd      socket_open_tcp                 ;05
566
        dd      socket_status                   ;06
567
        dd      socket_write_tcp                ;07
568
        dd      socket_close_tcp                ;08
569
        dd      is_localport_unused             ;09
570
        dd      app_socket_handler.10
571
        dd      socket_read_packet              ;11
572
endg
573
 
574
app_socket_handler:
575
;in ebx,ecx,edx,wsi
576
;out eax
577
        cmp     eax, 255
578
        je      stack_internal_status
579
 
580
        cmp     eax, 11
581
        ja      .fail                   ;if more than 15 then exit
582
 
583
        jmp     dword [f53call+eax*4]
584
 
585
.10:
586
        mov     eax, dword[drvr_cable]
587
        test    eax, eax
588
        jnz     @f                      ; if function is not implented, return -1
589
        or      al, -1
590
        ret
591
@@:
592
        jmp     dword[drvr_cable]
593
 
594
.fail:
595
        or      eax, -1
596
        ret
597
uglobal
598
  ARPTmp:
599
  times 14 db 0
600
endg
601
 
602
;***************************************************************************
603
;   Function
604
;      stack_internal_status
605
;
606
;   Description
607
;       Returns information about the internal status of the stack
608
;       This is only useful for debugging
609
;       It works with the ethernet driver
610
;       sub function in ebx
611
;       return requested data in eax
612
;
613
;***************************************************************************
614
; This sub function allows access to debugging information on the stack
615
; ecx holds the request:
616
; 100 : return length of empty queue
617
; 101 : return length of IPOUT QUEUE
618
; 102 : return length of IPIN QUEUE
619
; 103 : return length of NET1OUT QUEUE
620
; 200 : return # of ARP entries
621
; 201 : return size of ARP table ( max # entries )
622
; 202 : select ARP table entry #
623
; 203 : return IP of selected table entry
624
; 204 : return High 4 bytes of MAC address of selected table entry
625
; 205 : return low  2 bytes of MAC address of selected table entry
626
; 206 : return status word of selected table entry
627
; 207 : return Time to live of selected table entry
628
 
629
 
630
;  2 : return number of IP packets received
631
;  3 : return number of packets transmitted
632
;  4 : return number of received packets dumped
633
;  5 : return number of arp packets received
634
;  6 : return status of packet driver
635
;  ( 0 == not active, FFFFFFFF = successful )
636
 
637
 
638
stack_internal_status:
639
        cmp     ebx, 100
640
        jnz     notsis100
641
 
642
    ;  100 : return length of EMPTY QUEUE
643
        mov     ebx, EMPTY_QUEUE
644
        call    queueSize
645
        ret
646
 
647
notsis100:
648
        cmp     ebx, 101
649
        jnz     notsis101
650
 
651
    ;  101 : return length of IPOUT QUEUE
652
        mov     ebx, IPOUT_QUEUE
653
        call    queueSize
654
        ret
655
 
656
notsis101:
657
        cmp     ebx, 102
658
        jnz     notsis102
659
 
660
    ;  102 : return length of IPIN QUEUE
661
        mov     ebx, IPIN_QUEUE
662
        call    queueSize
663
        ret
664
 
665
notsis102:
666
        cmp     ebx, 103
667
        jnz     notsis103
668
 
669
    ;  103 : return length of NET1OUT QUEUE
670
        mov     ebx, NET1OUT_QUEUE
671
        call    queueSize
672
        ret
673
 
674
notsis103:
675
        cmp     ebx, 200
676
        jnz     notsis200
677
 
678
    ; 200 : return num entries in arp table
679
        movzx   eax, byte [NumARP]
680
        ret
681
 
682
notsis200:
683
        cmp     ebx, 201
684
        jnz     notsis201
685
 
686
    ; 201 : return arp table size
687
        mov     eax, 20; ARP_TABLE_SIZE
688
        ret
689
 
690
notsis201:
691
        cmp     ebx, 202
692
        jnz     notsis202
693
 
694
    ; 202 - read the requested table entry
695
    ; into a temporary buffer
696
    ; ecx holds the entry number
697
 
698
        mov     eax, ecx
699
        mov     ecx, 14; ARP_ENTRY_SIZE
700
        mul     ecx
701
 
702
        mov     ecx, [eax + ARPTable]
703
        mov     [ARPTmp], ecx
704
        mov     ecx, [eax + ARPTable+4]
705
        mov     [ARPTmp+4], ecx
706
        mov     ecx, [eax + ARPTable+8]
707
        mov     [ARPTmp+8], ecx
708
        mov     cx, [eax + ARPTable+12]
709
        mov     [ARPTmp+12], cx
710
        ret
711
 
712
notsis202:
713
        cmp     ebx, 203
714
        jnz     notsis203
715
 
716
    ; 203 - return IP address
717
        mov     eax, [ARPTmp]
718
        ret
719
 
720
notsis203:
721
        cmp     ebx, 204
722
        jnz     notsis204
723
 
724
    ; 204 - return MAC high dword
725
        mov     eax, [ARPTmp+4]
726
        ret
727
 
728
notsis204:
729
        cmp     ebx, 205
730
        jnz     notsis205
731
 
732
    ; 205 - return MAC ls word
733
        movzx   eax, word [ARPTmp+8]
734
        ret
735
 
736
notsis205:
737
        cmp     ebx, 206
738
        jnz     notsis206
739
 
740
    ; 206 - return status word
741
        movzx   eax, word [ARPTmp+10]
742
        ret
743
 
744
notsis206:
745
        cmp     ebx, 207
746
        jnz     notsis207
747
 
748
    ; 207 - return ttl word
749
        movzx   eax, word [ARPTmp+12]
750
        ret
751
 
752
notsis207:
753
        cmp     ebx, 2
754
        jnz     notsis2
755
 
756
    ;  2 : return number of IP packets received
757
        mov     eax, [ip_rx_count]
758
        ret
759
 
760
notsis2:
761
        cmp     ebx, 3
762
        jnz     notsis3
763
 
764
    ;  3 : return number of packets transmitted
765
        mov     eax, [ip_tx_count]
766
        ret
767
 
768
notsis3:
769
        cmp     ebx, 4
770
        jnz     notsis4
771
 
772
    ;  4 : return number of received packets dumped
773
        mov     eax, [dumped_rx_count]
774
        ret
775
 
776
notsis4:
777
        cmp     ebx, 5
778
        jnz     notsis5
779
 
780
    ;  5 : return number of arp packets received
781
        mov     eax, [arp_rx_count]
782
        ret
783
 
784
notsis5:
785
        cmp     ebx, 6
786
        jnz     notsis6
787
 
788
    ;  6 : return status of packet driver
789
    ;  ( 0 == not active, FFFFFFFF = successful )
790
        mov     eax, [eth_status]
791
        ret
792
 
793
notsis6:
794
        xor     eax, eax
795
        ret
796
 
797
 
798
 
799
;***************************************************************************
800
;   Function
801
;      stack_get_packet
802
;
803
;   Description
804
;       extracts an IP packet from the NET1 output queue
805
;       and sends the data to the calling process
806
;       pointer to data in edx
807
;       returns number of bytes read in eax
808
;
809
;***************************************************************************
810
stack_get_packet:
811
    ; Look for a buffer to tx
812
        mov     eax, NET1OUT_QUEUE
813
        call    dequeue
814
        cmp     ax, NO_BUFFER
815
        je      sgp_non_exit        ; Exit if no buffer available
816
 
817
        push    eax                 ; Save buffer number for freeing at end
818
 
819
        push    edx
820
    ; convert buffer pointer eax to the absolute address
821
        mov     ecx, IPBUFFSIZE
822
        mul     ecx
823
        add     eax, IPbuffs
824
        pop     edx
825
 
826
        push    eax                 ; save address of IP data
827
    ; Get the address of the callers data
828
        mov     edi, [TASK_BASE]
829
        add     edi, TASKDATA.mem_start
830
        add     edx, [edi]
831
        mov     edi, edx
832
        pop     eax
833
 
834
        mov     ecx, 1500       ; should get the actual number of bytes to write
835
        mov     esi, eax
836
        cld
837
        rep movsb               ; copy the data across
838
 
839
    ; And finally, return the buffer to the free queue
840
        pop     eax
841
        call    freeBuff
842
 
843
        mov     eax, 1500
844
        ret
845
 
846
sgp_non_exit:
847
        xor     eax, eax
848
        ret
849
 
850
 
851
 
852
;***************************************************************************
853
;   Function
854
;      stack_insert_packet
855
;
856
;   Description
857
;       writes an IP packet into the stacks receive queue
858
;       # of bytes to write in ecx
859
;       pointer to data in edx
860
;       returns 0 in eax ok, -1 == failed
861
;
862
;***************************************************************************
863
stack_insert_packet:
864
 
865
        mov     eax, EMPTY_QUEUE
866
        call    dequeue
867
        cmp     ax, NO_BUFFER
868
        je      sip_err_exit
869
 
870
        push    eax
871
 
872
    ; save the pointers to the data buffer & size
873
        push    edx
874
        push    ecx
875
 
876
    ; convert buffer pointer eax to the absolute address
877
        mov     ecx, IPBUFFSIZE
878
        mul     ecx
879
        add     eax, IPbuffs
880
 
881
        mov     edx, eax
882
 
883
    ; So, edx holds the IPbuffer ptr
884
 
885
        pop     ecx                 ; count of bytes to send
886
        mov     ebx, ecx            ; need the length later
887
        pop     eax                 ; get callers ptr to data to send
888
 
889
    ; Get the address of the callers data
890
        mov     edi, [TASK_BASE]
891
        add     edi, TASKDATA.mem_start
892
        add     eax, [edi]
893
        mov     esi, eax
894
 
895
        mov     edi, edx
896
        cld
897
        rep movsb               ; copy the data across
898
 
899
        pop     ebx
900
 
901
        mov     eax, IPIN_QUEUE
902
        call    queue
903
 
904
        inc     dword [ip_rx_count]
905
 
906
        mov     eax, 0
907
        ret
908
 
909
sip_err_exit:
910
        mov     eax, 0xFFFFFFFF
911
        ret
912