home *** CD-ROM | disk | FTP | other *** search
/ ProfitPress Mega CDROM2 …eeware (MSDOS)(1992)(Eng) / ProfitPress-MegaCDROM2.B6I / MISC / NETWORK / PCBRI120.ZIP / BRIDGE.INC < prev    next >
Encoding:
Text File  |  1991-02-19  |  11.2 KB  |  333 lines

  1. ;;******************************************************************************
  2. ;;                         bridge.inc      bridge.inc
  3. ;;******************************************************************************
  4. ;;
  5. ;;  Copyright (C) 1989 Northwestern University, 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. ;; Northwestern University 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. ;; 
  18. ;; Bridge.inc provides ethernet bridge cababilities.  Bridge will do bridging
  19. ;; between the interfaces provided to it.  It will also act like a IF object
  20. ;; and return packets that are directed to any of its interfaces.
  21. ;; 
  22. ;; The functions provided by this file are
  23. ;;
  24. ;;   BDG_DECLARE name, start_ifs, end_ifs, forward_ip
  25. ;;   BDG_DEFINE name
  26. ;;   BDG_IF_R_ACCESS_out_BX_CX_ES name, no_packet
  27. ;;   BDG_IF_R_CONT_in_BX_CX_ES_const_BX_CX_DX_BP_SI_DI_ES name, ok
  28. ;;   BDG_IF_R_FREE_const_BX_CX_BP_SI_DI_ES name
  29. ;;   BDG_IF_W_ACCESS_in_CX_out_DI_ES_const_BX_CX_BP name, no_buffer
  30. ;;   BDG_IF_W_WRITE_in_CX_const_BX_BP_ES name
  31. ;;   BDG_IF_SET_ADDRESS_in_SI_const_BX_CX_BP_DI_ES name
  32. ;;   BDG_IF_COPY_in_CX_SI_DI_ES_out_SI_DI_const_BX_BP_ES name
  33. ;;
  34. ;; Variables set by this module
  35. ;;
  36. ;;   bdg_&name&_declared                       ;; one if this interface exists
  37. ;;   if_&name&_address                         ;; the hardware address
  38. ;;   if_&name&_mtu                             ;; the maximum trans unit
  39. ;;
  40. ;;******************************************************************************
  41.  
  42.  
  43. ;;******************************************************************************
  44. ;;   BDG_DECLARE name, start_ifs, end_ifs, forward_ip  
  45. ;;      BDG_DECLARE declares a bridge made up of the ifs [start_ifs..end_ifs].
  46. ;;  All of these ifs are assumed to be declared to be PROMISCUOUS and
  47. ;;  if 'forward_ip' is not blank, then IP broadcasts and ARPS will be 
  48. ;;      forwarded, otherwize they will not
  49. ;;
  50. BDG_DECLARE MACRO name, start_ifs, end_ifs, forward_ip
  51.     .errb <name>
  52.     .errb <start_ifs>
  53.     .errb <end_ifs>
  54.  
  55.     if name ne 1
  56.         .err                ;; you are only alowed 1 bridge and it must be
  57.                             ;; named '1'
  58.     endif
  59.  
  60.     .DATA
  61.     bdg_&name&_declared  = 1
  62.     bdg_&name&_start_ifs = start_ifs-1
  63.     bdg_&name&_end_ifs = end_ifs
  64.     global bdg_&name&_table_ptr:word        ;; holds segement for table
  65.  
  66.     ifnb <forward_ip>
  67.         bdg_&name&_forw_ip   = 1
  68.     else
  69.         bdg_&name&_forw_ip   = 0
  70.     endif
  71.     .CODE
  72. ENDM
  73.  
  74.  
  75. ;;******************************************************************************
  76. ;;   BDG_DEFINE name
  77. ;;      sets asside memory for the bridge and initializes it.
  78. ;;      routine is a no-op if 'name' was not declared
  79. ;;
  80. BDG_DEFINE MACRO name
  81.     LOCAL loop1, loop2, loop3, table
  82.     .errb <name>
  83.  
  84. ifdef bdg_&name&_declared
  85.     .data
  86.     bdg_&name&_table_ptr dw ?                   ;; holds segment address of tab
  87.     .FarData?
  88.     table db 65535 dup (?)                      ;; set aside a whole segment
  89.                                                 ;; for the bridge table
  90.  
  91.     .CODE
  92.     mov AX, SEG table
  93.     mov bdg_&name&_table_ptr, AX                ;; remember where the table is
  94.  
  95.     mov ES, AX  
  96.     xor DI, DI
  97.     mov CX, 32768
  98.     xor AX, AX
  99.     rep
  100.     stosw                                       ;; null the bridge table
  101.  
  102. endif
  103. ENDM
  104.  
  105.  
  106. ;;******************************************************************************
  107. ;;   IF_R_ACCESS_out_BX_ES name, no_packet
  108. ;;       IF_R_ACCESS waits for the next packet to come from the the board
  109. ;;       associated with 'name' and returns a pointer to the begining of 
  110. ;;       an ethernet packet in BX:ES.  CX holds the length of the packet
  111. ;;       R_ACCESS jumps to 'no_packet' if there are no packets waiting to 
  112. ;;       be read in
  113. ;;       
  114. BDG_IF_R_ACCESS_out_BX_CX_ES MACRO name, no_packet
  115.     local got_packet, forward_all, forward, not_me, drop
  116.     local broadcast, broadcast_drop, around
  117.     .errb <no_packet>
  118.  
  119.     IF_R_ACCESS_out_BX_CX_ES name, no_packet
  120.  
  121.     mov AX, ES:[BX+4]       ;; is this my ethernet address?
  122.     cmp AX, word ptr if_&name&_address+4
  123.     jnz not_me
  124.     mov AX, ES:[BX+2]
  125.     cmp AX, word ptr if_&name&_address+2
  126.     jnz not_me
  127.     mov AX, ES:[BX]
  128.     cmp AX, word ptr if_&name&_address
  129.     jz got_packet
  130.     not_me:
  131.  
  132.     mov BP, DS                  ;; save DS
  133.     mov SI, BX
  134.  
  135.     mov AX, ES
  136.     mov ES, bdg_1_table_ptr     ;; ES:0 points to the table
  137.     mov DS, AX                  ;; DS:SI points to the packet
  138.  
  139.     add SI, 6                   ;; skip to source address of the packet
  140.  
  141.     mov DI, [SI+4]              ;; compute hash function ((LSB+MSB) * 8 mod 65k)
  142.     xor DI, [SI+2]              
  143.     shl DI, 1
  144.     shl DI, 1
  145.     shl DI, 1
  146.     movsw                       ;; save the ethernet address
  147.     movsw
  148.     movsw
  149.     mov AL, name            ;; and the fact that it is on this interface
  150.     stosb
  151.  
  152.     sub SI, 12                  ;; restore SI to the begining of the packet
  153.  
  154.     test byte ptr [SI], 1H      ;; is it a broadcast
  155.  
  156.     jnz broadcast
  157.  
  158.     mov DI, [SI+4]              ;; compute hash function ((LSB+MSB) * 8 mod 65k)
  159.     xor DI, [SI+2]              
  160.     shl DI, 1
  161.     shl DI, 1
  162.     shl DI, 1
  163.  
  164.     cmpsw
  165.     jnz forward_all         ;; didn't find in table
  166.     cmpsw
  167.     jnz forward_all         ;; didn't find in table
  168.     cmpsw
  169.     jnz forward_all         ;; didn't find in table
  170.     mov DS, BP              ;; restore DS
  171.     mov AL, ES:[DI]
  172.     cmp AL, name
  173.     jnz forward
  174.         drop:
  175.         IF_R_FREE_const_BX_CX_BP_SI_DI_ES name 
  176.         jmp no_packet
  177.  
  178.     forward:
  179.         mov BP, CX
  180.         IRP idx, <1,2,3,4,5,6,7,8>
  181.         local next
  182.         if (idx le bdg_1_end_ifs) and (idx gt bdg_1_start_ifs)
  183.         if idx ne (name+bdg_1_start_ifs)
  184.             cmp AL, idx
  185.             jnz next
  186.                 IF_W_ACCESS_in_CX_out_DI_ES_const_BX_CX_BP idx, drop
  187.                 mov SI, BX
  188.                 IF_COPY_in_CX_SI_DI_ES_out_SI_DI_const_BX_BP_ES name 
  189.                 mov CX, BP
  190.                 IF_W_WRITE_in_CX_const_BX_BP_ES idx
  191.             next:
  192.         endif
  193.         endif
  194.         endm
  195.        jmp drop
  196.  
  197.     forward_all:
  198.         mov DS, BP              ;; restore DS
  199.         mov BP, CX
  200.         IRP idx, <1,2,3,4,5,6,7,8>
  201.         if (idx le bdg_1_end_ifs) and (idx gt bdg_1_start_ifs)
  202.         if idx ne (name+bdg_1_start_ifs)
  203.             mov CX, BP
  204.             IF_W_ACCESS_in_CX_out_DI_ES_const_BX_CX_BP idx, drop
  205.             mov SI, BX
  206.             IF_COPY_in_CX_SI_DI_ES_out_SI_DI_const_BX_BP_ES name
  207.             mov CX, BP
  208.             IF_W_WRITE_in_CX_const_BX_BP_ES idx
  209.         endif
  210.         endif
  211.         endm
  212.        jmp drop
  213.     
  214.     broadcast:
  215.     mov AX, DS                  ;; restore ES
  216.     mov ES, AX
  217.     mov DS, BP                  ;; restore DS
  218.  
  219.     if bdg_1_forw_ip eq 0   ;; should we drop this because it is an IP or ARP packet?
  220.         mov AX, word ptr [SI+12]
  221.         cmp AX, 0008H           ;; is it an IP packet
  222.         jz broadcast_drop
  223.         cmp AX, 0608H           ;; is it an ARP packet
  224.         jz broadcast_drop
  225.     endif
  226.  
  227.     ;; if we don't drop it, then we must send it to all the interfaces
  228.     push ES
  229.     mov BP, CX          
  230.     IRP idx, <1,2,3,4,5,6,7,8>
  231.     if (idx le bdg_1_end_ifs) and (idx gt bdg_1_start_ifs)
  232.     if idx ne (name+bdg_1_start_ifs)
  233.         mov CX, BP
  234.         IF_W_ACCESS_in_CX_out_DI_ES_const_BX_CX_BP idx, drop
  235.         mov SI, BX
  236.         IF_COPY_in_CX_SI_DI_ES_out_SI_DI_const_BX_BP_ES name
  237.         mov CX, BP
  238.         IF_W_WRITE_in_CX_const_BX_BP_ES idx
  239.     endif
  240.     endif
  241.     endm
  242.     pop ES
  243.  
  244.     broadcast_drop:
  245.     ;; in either case, we also send the packet up to the higher level protocols
  246.     mov CX, BP          ;; restore the length
  247.     got_packet:
  248. ENDM
  249.  
  250.  
  251. ;;******************************************************************************
  252. ;;   IF_R_FREE_const_BX_CX_BP_SI_DI_ES  name
  253. ;;       After the client is through processing the packet returned by 
  254. ;;       IF_R_ACCESS, IF_R_FREE must be called to inform 'name' that the 
  255. ;;       memory that the packet was in can be reused for future packets.
  256. ;;
  257. BDG_IF_R_FREE_const_BX_CX_BP_SI_DI_ES MACRO name
  258.     local inside
  259.     .errb <name>
  260.  
  261.     IF_R_FREE_const_BX_CX_BP_SI_DI_ES name
  262. ENDM
  263.  
  264.  
  265. ;;******************************************************************************
  266. ;;   BDG_IF_R_CONT_in_BX_CX_ES name, ok
  267. ;;       IF_R_CONT determines if the packet returned by R_ACCESS in BX:ES
  268. ;;       of length CX is continuous.  If it is it jumps to 'ok' otherwise
  269. ;;       it just returns
  270. ;;
  271. BDG_IF_R_CONT_in_BX_CX_ES_const_BX_CX_DX_BP_SI_DI_ES MACRO name, ok
  272.     .errb <ok>
  273.  
  274.     IF_R_CONT_in_BX_CX_ES_const_BX_CX_DX_BP_SI_DI_ES name, ok
  275. ENDM
  276.  
  277.  
  278. ;;******************************************************************************
  279. ;;   IF_W_ACCESS_in_CX_out_DI_ES name, no_buffer
  280. ;;       IF_W_ACCESS returns a pointer to an output buffer for a packet.  The 
  281. ;;       pointer is returned in DI:ES.  If the ouptut buffer is busy, this 
  282. ;;       routine will jump to 'no_buffer'.  The output buffer  min(CX, 1536) 
  283. ;;       bytes long
  284. ;;
  285. BDG_IF_W_ACCESS_in_CX_out_DI_ES_const_BX_CX_BP MACRO name, no_buffer
  286.     .errb <no_buffer>
  287.  
  288.     IF_W_ACCESS_in_CX_out_DI_ES_const_BX_CX_BP name,no_buffer
  289. ENDM
  290.  
  291.  
  292. ;;******************************************************************************
  293. ;;   IF_W_WRITE_in_CX name
  294. ;;       IF_W_WRITE actually signals the ethernet board to write a packet to 
  295. ;;       the ethernet.  The packet is assumed to be in the buffer returned by 
  296. ;;       IF_W_ACCESS. CX is the length of the packet to send.  
  297. ;;
  298. BDG_IF_W_WRITE_in_CX_const_BX_BP_ES MACRO name
  299.     .errb <name>
  300.  
  301.     IF_W_WRITE_in_CX_const_BX_BP_ES name 
  302. ENDM
  303.  
  304.  
  305. ;;******************************************************************************
  306. ;;   IF_SET_ADDRESS_in_SI name
  307. ;;       IF_SET_ADDRESS_in_SI sets the hardware address to be the value
  308. ;;       pointed to by SI.  Note this function may be a no-op if the
  309. ;;       hardware address cannot be set (ETHERNET for example)
  310. ;;
  311. BDG_IF_SET_ADDRESS_in_SI_const_BX_CX_BP_DI_ES MACRO name
  312.     .errb <name>
  313.  
  314.     IF_SET_ADDRESS_in_SI_const_BX_CX_BP_DI_ES name 
  315. ENDM
  316.  
  317.  
  318. ;;******************************************************************************
  319. ;;   IF_COPY_in_CX_SI_DI_ES name
  320. ;;      IF_COPY_in_CX_SI_DI_ES copys a packet from the input buffer (pointed 
  321. ;;      to by SI and the segement register given in IF_DECLARE) to an output 
  322. ;;      buffer (pointed to by DI and dest_reg) of length CX.   It assumes the
  323. ;;      output buffer is contiguous.  (and the caller shouln't care if the 
  324. ;;      input buffer is contiguous)
  325. ;;
  326. BDG_IF_COPY_in_CX_SI_DI_ES_out_SI_DI_const_BX_BP_ES MACRO name
  327.     local wrap, done
  328.     .errb <name>
  329.  
  330.     IF_COPY_in_CX_SI_DI_ES_out_SI_DI_const_BX_BP_ES name
  331. ENDM
  332.  
  333.