home *** CD-ROM | disk | FTP | other *** search
/ PC Press: Internet / PC_PRESS.ISO / software / dos / misc / inar-100.exe / SRC / PCROUTE / PACKET.INC < prev    next >
Encoding:
Text File  |  1995-05-21  |  12.3 KB  |  391 lines

  1. ;;******************************************************************************
  2. ;;                         packet.inc      packet.inc
  3. ;;******************************************************************************
  4. ;;
  5. ;;  Copyright (C) 1989 Vance Morrison
  6. ;;
  7. ;;
  8. ;; Permission to view, compile, and modify for LOCAL (intra-organization) 
  9. ;; USE ONLY is hereby granted, provided that this copyright and permission 
  10. ;; notice appear on all copies.  Any other use by permission only.
  11. ;;
  12. ;; Vance Morrison makes no representations about the suitability 
  13. ;; of this software for any purpose.  It is provided "as is" without expressed 
  14. ;; or implied warranty.  See the copywrite notice file for complete details.
  15. ;;
  16. ;;******************************************************************************
  17. ;; packet.inc contains the interface driver for the the packet  driver 
  18. ;; (a la FTP software, drivers and info available from sun.soe.clarson.edu)
  19. ;;
  20. ;; Note that this interface driver is VERY inefficient.  basically packets
  21. ;; are copyied once on read and once again on write.   Thus this driver will
  22. ;; be at best 1/3 the speed of a native driver.  Nevertheless, this speed
  23. ;; may be acceptable, (and besides it gets all those people who want 3Com
  24. ;; support off my back).   There are other inefficiencies as well (saving
  25. ;; and restoring registers, waiting for packets to be sent etc), but even
  26. ;; so it will be usefull for low performance applications.
  27. ;;
  28. ;; Note that this these routines do not use any extended or high performance 
  29. ;; packet driver calls.  Only the basic calls are used
  30. ;;
  31. ;; The functions provided by this file are
  32. ;;
  33. ;;   PKT_DECLARE name, driver_int, driver_class, prom
  34. ;;   PKT_DEFINE name, fail
  35. ;;   PKT_IF_R_ACCESS_out_BX_CX_ES name, no_packet
  36. ;;   PKT_IF_R_CONT_in_BX_CX_ES_const_BX_CX_DX_BP_SI_DI_ES name, ok
  37. ;;   PKT_IF_R_FREE_const_BX_CX_BP_SI_DI_ES name
  38. ;;   PKT_IF_W_ACCESS_in_CX_out_DI_ES_const_BX_CX_BP name, no_buffer
  39. ;;   PKT_IF_W_WRITE_in_CX_const_BX_BP_ES name
  40. ;;   PKT_IF_SET_ADDRESS_in_SI_const_BX_CX_BP_DI_ES name
  41. ;;   PKT_IF_COPY_in_CX_SI_DI_ES_out_SI_DI_const_BX_BP_ES name
  42. ;;
  43. ;; Variables set by this module
  44. ;;
  45. ;;   pkt_&name&_declared                     ;; one if this interface exists
  46. ;;   if_&name&_address                       ;; the hardware address
  47. ;;   if_&name&_mtu                           ;; the maximum trans unit
  48. ;;
  49. ;;******************************************************************************
  50.  
  51. ;;******************************************************************************
  52. ;; data storage needed by this module
  53.  
  54. pkt_r_q_entry STRUC
  55.     pkt_q_rstart    DW ?
  56.     pkt_q_rend      DW ?
  57. pkt_r_q_entry ENDS
  58.  
  59. pkt_data  STRUC
  60.     pkt_bseg        DW ?
  61.     pkt_bend        DW ?
  62.     pkt_bstart      DW ?
  63. pkt_data ENDS
  64.  
  65.  
  66. ;;******************************************************************************
  67. ;;   IF_DECLARE name, driver_int driver_class, promiscuous
  68. ;;       declares an interface object.  driver_int is the interupt number
  69. ;;   to use to access the packet driver (60H-80H).  driver_class is
  70. ;;   the packet driver class of the card (Ethernet = 1)
  71. ;;
  72. PKT_DECLARE MACRO name, driver_int, driver_class, mtu_val, rbuff_len, promiscuous
  73.     .errb <name>
  74.     .errb <driver_int>
  75.  
  76.     .DATA
  77.     pkt_&name&_declared     = 1
  78.     pkt_&name&_drv_int   = driver_int
  79.     pkt_&name&_drv_class = driver_class
  80.     pkt_&name&_rbuff_len = rbuff_len
  81.  
  82.     pkt_&name&_rbuff   = name*100+1
  83.     pkt_&name&_rqueue  = name*100+2
  84.  
  85.     pkt_&name&_promiscuous = 0
  86.     ifnb <promiscuous>
  87.         pkt_&name&_promiscuous = 0&promiscuous
  88.     endif
  89.  
  90.     if_&name&_mtu = mtu_val
  91.     global pkt_&name&_wbuffer:byte
  92.     global pkt_&name&_data:pkt_data
  93.     global if_&name&_address:word 
  94.  
  95.     .CODE
  96.     global pkt_&name&_data_seg:word
  97.     global pkt_&name&_real_define:near
  98.     BUFF_DECLARE %pkt_&name&_rbuff, rbuff_len, pkt_&name&_rbuffer
  99.     QUEUE_DECLARE %pkt_&name&_rqueue, %((rbuff_len+127)/128), %(size pkt_r_q_entry)
  100. ENDM
  101.  
  102.  
  103. ;;******************************************************************************
  104. ;;   IF_DEFINE name, fail
  105. ;;      sets asside memory an name object and initializes it.  This
  106. ;;      routine is a no-op if 'name' was not declared.  It jumps to 'fail'
  107. ;;      if there was an error in  setup.
  108. ;;
  109. PKT_DEFINE MACRO name, fail
  110. ifdef pkt_&name&_declared
  111.     BUFF_DEFINE %pkt_&name&_rbuff 
  112.     QUEUE_DEFINE %pkt_&name&_rqueue
  113.     call pkt_&name&_real_define
  114.     or AX, AX
  115.     jnz fail
  116. endif
  117. ENDM
  118.  
  119.  
  120. PKT_REAL_DEFINE MACRO name
  121.     local pkt_read_task, got_driver, got_address, size_check, no_room, done
  122.     local set_prom, type_count, type_loop, type_done, pkt_handle
  123.     .errb <name>
  124.  
  125. ifdef pkt_&name&_declared
  126.     .DATA
  127.     type_count         DW ?
  128.     if pkt_&name&_promiscuous eq 1
  129.         pkt_handle     DW ?
  130.     endif
  131.     if_&name&_address  DW 3 DUP (0)
  132.     pkt_&name&_wbuffer DB 1536 dup (0)
  133.     pkt_&name&_data    pkt_data      <>  ;; create storage needed
  134.  
  135.     .FARDATA? pkt_&name&_bseg
  136.     pkt_&name&_rbuffer DB pkt_&name&_rbuff_len dup (?)
  137.  
  138.     .CODE
  139.     ;;*****************************************************************
  140.     pkt_&name&_real_define:
  141.     mov word ptr CS:pkt_&name&_data_seg, DS
  142.     mov AX, SEG pkt_&name&_rbuffer
  143.     mov pkt_&name&_data.pkt_bseg, AX
  144.     mov ES, AX
  145.     mov DI, offset pkt_&name&_rbuffer
  146.     mov CX, pkt_&name&_rbuff_len
  147.     xor AL, AL
  148.     rep
  149.     stosb
  150.  
  151.     mov AX, word ptr eth_&name&_data.eth_read_cnt
  152.     inc AX
  153.     mov word ptr type_count, AX
  154.     mov SI, offset eth_&name&_data.eth_read_jmp.eth_read_type
  155.  
  156.     type_loop:
  157.     dec word ptr type_count
  158.     jz type_done
  159.     push SI             ;; save packet type pointer
  160.     mov AH, 2           ;; access_type driver call
  161.     mov AL, pkt_&name&_drv_class    ;; driver class
  162.     mov DL, 0           ;; wildcard number
  163.     mov BX, 0FFFFH      ;; wildcard Type
  164.     mov CX, (size eth_read_type)  ;; length of packet type field
  165.     mov DI, CS          ;; point to my packet receiver
  166.     mov ES, DI
  167.     mov DI, offset pkt_read_task
  168.     stc 
  169.     PKT_CALL_DRIVER name
  170.     jnc got_driver
  171.         pop AX
  172.         mov DL, DH
  173.         xor DH, DH
  174.         mov AX, DX
  175.         ret
  176.     got_driver:
  177.     pop SI
  178.     add SI, (size eth_jmp_entry)
  179.     jmp type_loop
  180.  
  181.     type_done:
  182.     if pkt_&name&_promiscuous eq 1
  183.         mov word ptr pkt_handle, AX
  184.     endif
  185.  
  186.     mov BX, AX
  187.     mov AH, 6           ;; get ethernet address 
  188.     mov DX, DS
  189.     mov ES, DX
  190.     mov DI, offset if_&name&_address
  191.     mov CX, 6           ;; length of address buffer
  192.     stc
  193.     PKT_CALL_DRIVER name
  194.     jnc got_address
  195.         mov DL, DH
  196.         xor DH, DH
  197.         mov AX, DX
  198.         ret
  199.     got_address:
  200.  
  201.     if pkt_&name&_promiscuous eq 1
  202.         mov BX, word ptr pkt_handle
  203.         mov AH, 20      ;; set recieve mode
  204.         mov CX, 6       ;; to recieve all packets
  205.         stc
  206.         PKT_CALL_DRIVER name
  207.         jnc set_prom
  208.             mov DL, DH
  209.             xor DH, DH
  210.             mov AX, DX
  211.             ret
  212.         set_prom:
  213.     endif
  214.  
  215.     xor AX, AX
  216.     sti              ;; turn on interupts if they are not already on
  217.     ret
  218.  
  219.     ;;*********************************************************************
  220.     ;; 'interupt' routine
  221.     pkt_&name&_data_seg: DW 0
  222.  
  223.     pkt_read_task:
  224.     push DS
  225.     segcs
  226.     mov DS, word ptr pkt_&name&_data_seg
  227.     or AX, AX
  228.     jz size_check
  229.         QUEUE_ENQUEUE_out_DI_const_BX_CX_DX_BP_SI_ES %pkt_&name&_rqueue, done
  230.         mov AX, pkt_&name&_data.pkt_bstart
  231.         mov [DI+pkt_q_rstart], AX
  232.         mov AX, pkt_&name&_data.pkt_bend
  233.         mov [DI+pkt_q_rend], AX
  234.         done:
  235.         pop DS
  236.         retf
  237.     size_check:
  238.        BUFF_CHECK_in_CX_out_SI_DI_const_BX_CX_DX_BP_ES %pkt_&name&_rbuff,no_room
  239.            BUFF_GET_in_DI_const_AX_BX_CX_DX_BP_SI_DI_ES %pkt_&name&_rbuff
  240.            mov pkt_&name&_data.pkt_bstart, SI
  241.            mov pkt_&name&_data.pkt_bend, DI
  242.            mov DI, SI
  243.            mov ES, pkt_&name&_data.pkt_bseg
  244.            pop DS
  245.            retf
  246.         no_room:
  247.            xor DI, DI
  248.            mov ES, DI
  249.            pop DS
  250.            retf
  251.  
  252. endif
  253. ENDM
  254.  
  255.  
  256. ;;******************************************************************************
  257. ;;   IF_R_ACCESS_out_BX_ES name, no_packet
  258. ;;       IF_R_ACCESS checks for the next packet to come from the the board
  259. ;;       associated with 'name' and returns a pointer to the begining of 
  260. ;;       an ethernet packet in BX:ES.  CX holds the length of the packet
  261. ;;       R_ACCESS jumps to 'no_packet' if there are no packets waiting to 
  262. ;;       be read in
  263. ;;       
  264. PKT_IF_R_ACCESS_out_BX_CX_ES MACRO name, no_packet
  265.     .errb <no_packet>
  266.  
  267.     QUEUE_HEAD_out_SI_const_AX_BX_CX_DX_BP_DI_ES %pkt_&name&_rqueue, no_packet
  268.     mov BX, [SI+pkt_q_rstart]
  269.     mov CX, [SI+pkt_q_rend]
  270.     sub CX, BX
  271.     mov ES, pkt_&name&_data.pkt_bseg
  272. ENDM
  273.  
  274.  
  275. ;;******************************************************************************
  276. ;;   IF_R_FREE_const_BX_CX_BP_SI_DI_ES  name
  277. ;;       After the client is through processing the packet returned by 
  278. ;;       IF_R_ACCESS, IF_R_FREE must be called to inform 'name' that the 
  279. ;;       memory that the packet was in can be reused for future packets.
  280. ;;
  281. PKT_IF_R_FREE_const_BX_CX_BP_SI_DI_ES MACRO name
  282.     local done
  283.     .errb <name>
  284.  
  285.     cli
  286.     QUEUE_HEAD_out_SI_const_AX_BX_CX_DX_BP_DI_ES %pkt_&name&_rqueue, done
  287.     mov DI, [SI+pkt_q_rend]
  288.     BUFF_FREE_in_DI_const_AX_BX_CX_DX_BP_SI_DI_ES %pkt_&name&_rbuff
  289.     QUEUE_DEQUEUE_in_SI_const_AX_BX_CX_DX_BP_DI_ES %pkt_&name&_rqueue
  290.     done:
  291.     sti
  292. ENDM
  293.  
  294.  
  295. ;;******************************************************************************
  296. ;;   PKT_IF_R_CONT_in_BX_CX_ES name, ok
  297. ;;       IF_R_CONT determines if the packet returned by R_READ in BX:ES
  298. ;;       of length CX is continuous.  If it is it jumps to 'ok' otherwise
  299. ;;       it just returns
  300. ;;
  301. PKT_IF_R_CONT_in_BX_CX_ES_const_BX_CX_DX_BP_SI_DI_ES MACRO name, ok
  302.     .errb <ok>
  303.  
  304.     jmp ok      ;; is it always continuous
  305. ENDM
  306.  
  307.  
  308. ;;******************************************************************************
  309. ;;   IF_W_ACCESS_in_CX_out_DI_ES name, no_buffer
  310. ;;       IF_W_ACCESS returns a pointer to an output buffer for a packet.  The 
  311. ;;       pointer is returned in DI:ES.  If the ouptut buffer is busy, this 
  312. ;;       routine will jump to 'no_buffer'.  The output buffer  min(CX, 1536) 
  313. ;;       bytes long
  314. ;;
  315. PKT_IF_W_ACCESS_in_CX_out_DI_ES_const_BX_CX_BP MACRO name, no_buffer
  316.     .errb <no_buffer>
  317.  
  318.    mov DI, offset pkt_&name&_wbuffer
  319.    mov AX, DS
  320.    mov ES, AX
  321. ENDM
  322.  
  323.  
  324. ;;******************************************************************************
  325. ;;   IF_W_WRITE_in_CX name
  326. ;;       IF_W_WRITE actually signals the ethernet board to write a packet to 
  327. ;;       the ethernet.  The packet is assumed to be in the buffer returned by 
  328. ;;       IF_W_ACCESS. CX is the length of the packet to send.  
  329. ;;
  330. PKT_IF_W_WRITE_in_CX_const_BX_BP_ES MACRO name
  331.     .errb <name>
  332.  
  333.     push BX
  334.     push BP
  335.     push ES
  336.  
  337.     mov AH, 4               ;; set_pkt command
  338.     mov SI, offset pkt_&name&_wbuffer   ;; the packet to send
  339.                             ;; DS is OK as it stands
  340.                             ;; CX is also fine as is
  341.     PKT_CALL_DRIVER name
  342.     pop ES
  343.     pop BP
  344.     pop BX
  345. ENDM
  346.  
  347.  
  348. ;;******************************************************************************
  349. ;;   IF_SET_ADDRESS_in_SI name
  350. ;;       IF_SET_ADDRESS_in_SI sets the hardware address to be the value
  351. ;;       pointed to by SI.  Note this function may be a no-op if the
  352. ;;       hardware address cannot be set (ETHERNET for example)
  353. ;;
  354.  
  355. PKT_IF_SET_ADDRESS_in_SI_const_BX_CX_BP_DI_ES MACRO name
  356.     .err    ;; we don't support setting ethernet addresses (yet)
  357.     ENDM
  358.  
  359.  
  360. ;;******************************************************************************
  361. ;;   IF_COPY_in_CX_SI_DI_ES_out_SI_DI name
  362. ;;      IF_COPY_in_CX_SI_DI_ES copys a packet from the input buffer (pointed 
  363. ;;      to by SI and the segement register given in IF_DECLARE) to an output 
  364. ;;      buffer (pointed to by DI and ES) of length CX.   It assumes the
  365. ;;      output buffer is contiguous.  (and the caller shouln't care if the 
  366. ;;      input buffer is contiguous)
  367. ;;
  368. PKT_IF_COPY_in_CX_SI_DI_ES_out_SI_DI_const_BX_BP_ES MACRO name
  369.     .errb <name>
  370.  
  371.     ;; since DS points to the data segment, we are ready to go!!
  372.     inc CX
  373.     shr CX,1
  374.     rep movsw
  375. ENDM
  376.  
  377. ;;******************************************************************************
  378. ;; PKT_CALL_DRIVER calls the drivers, but it also makes sure that the
  379. ;; segment registers are preserved.
  380.  
  381. PKT_CALL_DRIVER MACRO name
  382.     .errb <name>
  383.  
  384.     push DS
  385.     push SS
  386.     int pkt_&name&_drv_int
  387.     pop SS
  388.     pop DS
  389. ENDM
  390.  
  391.