home *** CD-ROM | disk | FTP | other *** search
/ The World of Computer Software / World_Of_Computer_Software-02-385-Vol-1of3.iso / p / pcrte224.zip / SOURCE.ZIP / IP.INC < prev    next >
Text File  |  1992-06-09  |  29KB  |  904 lines

  1. ;;************************************************************************* 
  2. ;;                         ip.inc       ip.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. ;; Routines provided by this module
  19. ;;
  20. ;;   IP_DECLARE name, router, dls, icmp
  21. ;;   IP_DEFINE name
  22. ;;   IP_R_READ name, code_label
  23. ;;   IP_R_RETURN name
  24. ;;   IP_R_SRC_in_SI_ES_out_AX_BX_const_CX_DX_BP_SI_DI_ES name
  25. ;;   IP_R_BROAD_in_SI_ES_const_CX_DX_BP_SI_DI_ES name, broadcast
  26. ;;   IP_R_HEADER_in_ES_out_SI_const_BX_CX_DX_BP_DI_ES name
  27. ;;   IP_W_ACCESS_in_AX_BX_CX_DL_out_AX_DI_ES name
  28. ;;   IP_W_WRITE_in_CX name
  29. ;;   IP_COMPUTE_NET_in_AX_BX_out_AX_BX_const_CX_DX_BP_SI_DI_ES dls
  30. ;;
  31. ;;  Variables Provided by this Module (READ ONLY!!!)
  32. ;;
  33. ;;  ip_&name&_dls           ;; 1..dls are the names of the IP_DL objects
  34. ;;
  35. ;;*****************************************************************************
  36.  
  37. ;; IP packet header def
  38.  
  39. ;; masks for the Flag field
  40. IP_DONT_FRAG    = 4000H
  41. IP_MORE_FRAG    = 2000H
  42. SWAPPED_IP_DONT_FRAG    = 40H
  43. SWAPPED_IP_MORE_FRAG    = 20H
  44.  
  45. ip      STRUC               ;; and IP packet
  46.     ip_ver_size     DB ?
  47.     ip_tos          DB ?
  48.     ip_length       DW ?
  49.     ip_id           DW ?
  50.     ip_frag         DW ?
  51.     ip_ttl          DB ?
  52.     ip_proto        DB ?
  53.     ip_check        DW ?
  54.     ip_src          DD ?
  55.     ip_dst          DD ?
  56. ip  ENDS
  57.  
  58.  
  59. ip_data  STRUC
  60.     ip_write_dst    DD ?
  61.     ip_write_src    DD ?
  62.     ip_write_off    DW ?
  63.     ip_write_seg    DW ?
  64.     ip_write_gate   DW ?
  65.     ip_write_proto  DB ?
  66.     ip_write_dl     DB ?
  67.     ip_write_id     DW ?
  68.     ip_packet       DW (dl_ip_max_mtu/2 + 16) dup (0)
  69.     ip_header       DW 32 dup (0)
  70.  
  71.     ip_broadcast    DB ?
  72.     ip_read_head    DW ?
  73.     ip_read_jmp     DW 32 dup (0)
  74. ip_data  ENDS
  75.  
  76.  
  77. ;;******************************************************************************
  78. ;;   IP_DECLARE   name, dls 
  79. ;;      IP_DECLARE declares a network ojbect that will route packets
  80. ;;      using 'router' as its routing table to the Data Link objects
  81. ;;      1..dls.  
  82. ;;
  83. IP_DECLARE MACRO name, router, dls, icmp
  84.  
  85.     .DATA
  86.     ip_&name&_dls = dls
  87.     ip_&name&_router = router
  88.     ip_&name&_icmp = icmp
  89.     global ip_&name&_data:ip_data
  90.  
  91.     .CODE
  92.     IRP idx, <1,2,3,4,5,6,7,8>
  93.     if idx le ip_&name&_dls
  94.         IP_DECLARE_HELPER name, idx
  95.     endif
  96.     endm
  97.  
  98.     global ip_&name&_read_packet:near
  99.     global ip_&name&_prot_unreach:near
  100.     global ip_&name&_w_access:near
  101.     global ip_&name&_w_write:near
  102.     global ip_&name&_real_define:near
  103. ENDM
  104.  
  105. IP_DECLARE_HELPER MACRO name, dl
  106.     global ip_&name&_dl_&dl&_read_start:near
  107. ENDM
  108.  
  109.  
  110. ;;*****************************************************************************
  111. ;;   IP_DEFINE name
  112. ;;       IP_DEFINE defines all of the data structures needed by IP and
  113. ;;       initializes them.
  114. ;;
  115. IP_DEFINE MACRO name
  116.     call ip_&name&_real_define
  117. ENDM
  118.  
  119. IP_REAL_DEFINE MACRO name
  120.     local around, skip
  121.     .errb <name>
  122.  
  123. ifdef ip_&name&_dls
  124.  
  125.     .DATA
  126. ip_&name&_data   ip_data  <>
  127.  
  128.     .CODE
  129.     ip_&name&_real_define:
  130.     jmp around                  ;; declare the 'this node' IP packet processor
  131.         ip_&name&_read_packet:
  132.             IP_PACKET_in_AX_BX_CX_ES name
  133.             RET 
  134.  
  135.         ip_&name&_prot_unreach:
  136.             cmp ip_&name&_data.ip_broadcast, 0
  137.             jnz skip
  138.             mov SI, BX
  139.             IP_R_HEADER_in_ES_out_SI_const_BX_CX_DX_BP_DI_ES name
  140.             ICMP_ERROR_in_SI_ES %ip_&name&_icmp, ICMP_UNREACHABLE, ICMP_UNREACH_PROTO, name
  141.             skip:
  142.             RET
  143.  
  144.         ip_&name&_w_access:
  145.             IP_REAL_W_ACCESS_in_AX_BX_CX_DL_out_AX_DI_ES name
  146.             RET
  147.  
  148.         ip_&name&_w_write:
  149.             IP_REAL_W_WRITE_in_CX name, %ip_&name&_w_write
  150.             RET
  151.  
  152.     around:
  153.         ;; initialize the jump table
  154.     mov AX, DS                              ;; initialize jump table
  155.     mov ES, AX
  156.     mov DI, offset ip_&name&_data.ip_read_jmp
  157.     mov AX, offset ip_&name&_prot_unreach
  158.     mov CX, 32
  159.     rep
  160.     stosw
  161.  
  162.         ;; do all per DL initilization
  163.     IRP idx, <1,2,3,4,5,6,7,8>
  164.     if idx le ip_&name&_dls
  165.         IP_INIT_DL name, idx
  166.     endif
  167.     endm
  168.  
  169.     RET
  170. endif
  171. ENDM
  172.  
  173.  
  174. ;;*****************************************************************************
  175. ;; IP_R_READ name, proto, code_label
  176. ;;      IP_READ declares that the code starting at 'code_label' should
  177. ;;      be called when a IP packet with protocol 'proto' is read in
  178. ;;      The data in the IP packet is passed to the object in BX:ES the 
  179. ;;      protocol type in AX and the length of the data in CX. 
  180. ;;      When the code is done it should execute a RET instruction
  181. ;;      If the source address is requires IP_R_SRC should be called
  182. ;;
  183. IP_R_READ MACRO name, proto, code_label
  184.    .errb <code_label>
  185.  
  186.     mov word ptr ip_&name&_data.ip_read_jmp+2*(proto mod 32), offset code_label
  187. ENDM
  188.  
  189. ;;*****************************************************************************
  190. ;; IP_R_SRC_in_SI_ES_out_AX_BX name
  191. ;;      IP_R_SRC returns the source of the IP data packet pointed to by SI:ES
  192. ;;      that was given to the IP_R_READ routine.  The IP address is put in
  193. ;;      AX,BX
  194. ;;
  195. IP_R_SRC_in_SI_ES_out_AX_BX_const_CX_DX_BP_SI_DI_ES MACRO name
  196.    .errb <name>
  197.  
  198.    push SI
  199.    IP_R_HEADER_in_ES_out_SI_const_BX_CX_DX_BP_DI_ES name
  200.    add SI, ip_src
  201.    mov AX, word ptr ES:[SI]
  202.    mov BX, word ptr ES:[SI+2]
  203.    pop SI
  204. ENDM
  205.  
  206. ;;*****************************************************************************
  207. ;; IP_R_BROAD_in_SI_ES name, broadcast
  208. ;;      IP_R_BROAD jumps to 'broadcast' if the IP packet pointed to by SI:ES
  209. ;;      is a broadcast.  
  210. ;;
  211. IP_R_BROAD_in_SI_ES_const_CX_DX_BP_SI_DI_ES MACRO name, broadcast
  212.    .errb <name>
  213.  
  214.     cmp ip_&name&_data.ip_broadcast, 0
  215.     jnz broadcast
  216. ENDM
  217.  
  218. ;;*****************************************************************************
  219. ;;   IP_R_HEADER_in_ES_out_SI_const_BX_CX_DX_BP_DI_ES name
  220. ;; IP_R_HEADER_in_SI_ES_out_DI returns the IP header for the packet pointed
  221. ;; to by SI:ES.  This routine must only be called in the routine specified
  222. ;; in R_READ.  (this is meant so that you can send ICMP packets)
  223. ;;
  224. IP_R_HEADER_in_ES_out_SI_const_BX_CX_DX_BP_DI_ES MACRO name
  225.    .errb <name>
  226.  
  227.     mov SI, word ptr ip_&name&_data.ip_read_head        ;; save header pointer
  228. ENDM
  229.  
  230.  
  231.  
  232. ;;*****************************************************************************
  233. ;; IP_W_ACCESS_in_AX_BX_CX_DL_out_AX_DI_ES name
  234. ;;      IP_W_ACCESS retrieves a buffer to write the data for an IP packet.  
  235. ;;      AX,BX holds the destination IP address of the packet and DL holds
  236. ;;      the protocol number of the packet.   The output buffer is returned
  237. ;;      in DI:ES.  This routine might fail if CX exceeds the MTU of the
  238. ;;      interface.  Thus it is only guarenteed to succeed when 
  239. ;;      CX <= dl_ip_min_mtu.  AX is 0 if everything was successful.
  240. ;;
  241. IP_W_ACCESS_in_AX_BX_CX_DL_out_AX_DI_ES MACRO name
  242.     local call_OK
  243.  
  244.     CALL ip_&name&_w_access
  245. ENDM
  246.  
  247. ;;*****************************************************************************
  248. ;; IP_REAL_W_ACCESS is the real provider of the W_ACCESS service.  
  249. ;;
  250. IP_REAL_W_ACCESS_in_AX_BX_CX_DL_out_AX_DI_ES MACRO name
  251.     local done, jmp_table, fail, return, forme
  252.     .errb <name>
  253.  
  254.     .DATA                                   ;; declare the jump table 
  255. jmp_table  dw   done                        ;; dl 0 is undefined
  256.     IRP idx, <1,2,3,4,5,6,7,8>
  257.     if idx le ip_&name&_dls 
  258.         IP_INIT_DL_JMP_TAB name, idx, write_access
  259.     endif
  260.     endm
  261.  
  262.     .CODE
  263.     mov word ptr ip_&name&_data.ip_write_dst, AX            ;; save address 
  264.     mov word ptr ip_&name&_data.ip_write_dst+2, BX
  265.     mov byte ptr ip_&name&_data.ip_write_proto, DL
  266.  
  267.     mov BP, CX                              ;; save CX
  268.  
  269.     mov CX, BX
  270.     IP_COMPUTE_NET_in_AX_BX_out_AX_BX_const_CX_DX_BP_SI_DI_ES %ip_&name&_dls
  271.     ROUTE_FIND_in_AX_BX_CX_out_AX_DL_const_BP_ES %ip_&name&_router, forme, fail
  272.     mov byte ptr ip_&name&_data.ip_write_dl, DL
  273.     mov word ptr ip_&name&_data.ip_write_gate, AX
  274.  
  275.     xor DH, DH                              ;; set up jump to proper DL
  276.     shl DX, 1
  277.     mov DI, offset jmp_table
  278.     add DI, DX
  279.     jmp [DI]
  280.  
  281.     forme:
  282.     fail:
  283.         xor AX, AX
  284.         dec AX
  285.         jmp return
  286.  
  287.         ;; the above jump goes to one of the code fragments below
  288.     IRP idx, <1,2,3,4,5,6,7,8>
  289.     if idx le ip_&name&_dls 
  290.         IP_INIT_DL_LABEL name, idx, write_access
  291.         IP_SAVE_SRC name, idx
  292.         mov CX, BP                      ;; restore CX
  293.         cmp CX, dl_ip_min_mtu           ;; enforce length restriction
  294.         ja  fail
  295.         DL_IP_W_ACCESS_in_CX_out_DI_ES_const_CX_BP idx, fail
  296.         jmp done
  297.     endif
  298.     endm
  299.         ;; the above code does NOT fall through
  300.     done:
  301.     mov word ptr ip_&name&_data.ip_write_off, DI
  302.     mov word ptr ip_&name&_data.ip_write_seg, ES
  303.     add DI, size ip
  304.     xor AX, AX
  305.     return:
  306. ENDM
  307.  
  308. IP_SAVE_SRC MACRO name, dl
  309.     mov AX, word ptr dl_ip_&dl&_ip
  310.     mov word ptr ip_&name&_data.ip_write_src, AX
  311.     mov AX, word ptr dl_ip_&dl&_ip+2
  312.     mov word ptr ip_&name&_data.ip_write_src+2, AX
  313. ENDM
  314.  
  315.  
  316. ;;*****************************************************************************
  317. ;; IP_W_WRITE_in_CX name
  318. ;;      IP_W_WRITE tells the IP interface to send the PACKET that is been
  319. ;;      loaded into the buffer DI:ES.  The length of the packet is in CX
  320. ;;      note that this IP level does NOT support fragmentation, so CX better
  321. ;;      be less than the dl_ip_min_mtu
  322. ;;
  323. IP_W_WRITE_in_CX MACRO name
  324.     .errb <name>
  325.  
  326.     CALL ip_&name&_w_write
  327. ENDM
  328.  
  329. ;;*****************************************************************************
  330. ;;
  331. ;;      IP_REAL_W_WRITE_in_CX is the real provider of the W_WRITE service.
  332. ;;      it is identical in function to IP_W_WRITE.
  333. ;;
  334. IP_REAL_W_WRITE_in_CX MACRO name
  335.     local done, jmp_table
  336.     .errb <name>
  337.  
  338.     .DATA                                   ;; declare the jump table 
  339. jmp_table  dw   done                        ;; dl 0 is undefined
  340.     IRP idx, <1,2,3,4,5,6,7,8>
  341.     if idx le ip_&name&_dls 
  342.         IP_INIT_DL_JMP_TAB name, idx, write_it
  343.     endif
  344.     endm
  345.  
  346.     .CODE
  347.     les DI, dword ptr ip_&name&_data.ip_write_off
  348.     mov AX, 0045H               ;; byte swapped length = 5 version = 4 tos = 0
  349.     mov BX, AX
  350.     stosw
  351.     add CX, size ip
  352.     mov AX, CX                  ;; the length
  353.     xchg AL, AH
  354.     add BX, AX
  355.     stosw
  356.     mov AX, word ptr ip_&name&_data.ip_write_id 
  357.     adc BX, AX
  358.     stosw
  359.     inc AX
  360.     mov word ptr ip_&name&_data.ip_write_id, AX
  361.     mov AX, 0
  362.     stosw
  363.     mov AL, 100                 ;; the time to live
  364.     mov AH, byte ptr ip_&name&_data.ip_write_proto
  365.     adc BX, AX
  366.     stosw
  367.     inc DI 
  368.     inc DI                      ;; skip checksum
  369.     mov SI, offset ip_&name&_data.ip_write_src
  370.     lodsw
  371.     adc BX, AX
  372.     stosw
  373.     lodsw
  374.     adc BX, AX
  375.     stosw
  376.     mov SI, offset ip_&name&_data.ip_write_dst
  377.     lodsw
  378.     adc BX, AX
  379.     stosw
  380.     lodsw
  381.     adc BX, AX
  382.     adc BX, 0
  383.     stosw
  384.  
  385.     sub DI, 10
  386.     not BX
  387.     mov AX, BX
  388.     stosw
  389.  
  390.         ;; set out the packet
  391.     mov AX, word ptr ip_&name&_data.ip_write_gate
  392.  
  393.     xor DH, DH                              ;; set up jump to proper DL
  394.     mov DL, byte ptr ip_&name&_data.ip_write_dl
  395.     shl DX, 1
  396.     mov DI, offset jmp_table
  397.     add DI, DX
  398.     jmp [DI]
  399.  
  400.         ;; the above jump goes to one of the code fragments below
  401.     IRP idx, <1,2,3,4,5,6,7,8>
  402.     if idx le ip_&name&_dls 
  403.         IP_INIT_DL_LABEL name, idx, write_it
  404.         DL_IP_W_WRITE_in_AX_CX_const_BP idx
  405.         jmp done
  406.     endif
  407.     endm
  408.         ;; the above code does NOT fall through
  409.     done:
  410. ENDM
  411.  
  412.  
  413. ;;*****************************************************************************
  414. ;; IP_INIT_DL name, dl
  415. ;;      IP_INIT_DL initializes the data link interface 'dl' 
  416.  
  417. IP_INIT_DL MACRO name, dl
  418.     local around
  419.     .errb <dl>
  420.  
  421.     jmp around
  422.     ;;  This stuff can be compiled seperately
  423.     ;   IP_DL_PACKET_in_BX_ES name, dl
  424.     ;   DL_IP_R_RETURN dl
  425.             ;; This does NOT fall through
  426.  
  427.     around:
  428.     mov AX, DS          ;; add the route for each directly connected interface
  429.     mov ES, AX
  430.     xor CX, CX
  431.     mov SI, offset dl_ip_&dl&_net
  432.     mov DI, offset dl_ip_&dl&_ip
  433.     ROUTE_ADD_in_CX_SI_DI_ES_const_DI_ES %ip_&name&_router
  434.  
  435.     DL_IP_R_READ dl, ip_&name&_dl_&dl&_read_start   ;; schedule the read
  436. ENDM
  437.  
  438.  
  439. ;;*****************************************************************************
  440. ;; IP_DL_PACKET_in_BX_ES name, read_dl
  441. ;;      IP_DL_PACKET_in_BX_ES does the proessing of a packet that came from
  442. ;;      a data link interface BX:ES points to the begining of the IP packet. 
  443. ;;      this is the routeine that does the routing and if it for this node
  444. ;;      calls IP_PACKET_in_BX_ES
  445. ;;
  446. IP_DL_PACKET_in_BX_ES MACRO name, read_dl
  447.     local forme, jmp_table, drop, ip_write_sav, ip_write_gate, ip_write_size
  448.     local ip_write_sav_seg
  449.     local drop_ttl, drop_route, broad_forme, redirect, continue_forme, ip_ok
  450.     .errb <read_dl>
  451.     
  452.     .DATA                                   ;; declare the jump table 
  453. jmp_table  dw   drop                        ;; dl 0 is undefined
  454.     IRP idx, <1,2,3,4,5,6,7,8>
  455.     if idx le ip_&name&_dls 
  456.         IP_INIT_DL_JMP_TAB name, idx, read_dl&_write_start
  457.     endif
  458.     endm
  459.  
  460. ip_write_size    DW  ?
  461. ip_write_sav     DW  ?
  462. ip_write_sav_seg DW  ?
  463. ip_write_gate    DW  ?
  464.  
  465.     .CODE
  466.     ip_&name&_dl_&read_dl&_read_start:
  467.     mov ip_write_sav, BX
  468.  
  469.     mov CX, word ptr ES:[BX+ip_length]      ;; make sure length reasonable
  470.     xchg CH, CL                             ;; byte swap
  471.  
  472.     cmp CX, dl_ip_&read_dl&_mtu
  473.     ja drop
  474.     mov ip_write_size, CX
  475.  
  476.     DL_IP_IS_BROADCAST_in_BX_ES_const_AX_BX_CX_DX_BP_DI_ES read_dl
  477.     jnz broad_forme 
  478.  
  479.     mov BP, BX                                      ;; save BX
  480.     mov AX, word ptr ES:[BX+ip_dst]                 ;; get an IP packet
  481.     mov BX, word ptr ES:[BX+ip_dst+2]
  482.  
  483.     mov CX, BX
  484.     IP_COMPUTE_NET_in_AX_BX_out_AX_BX_const_CX_DX_BP_SI_DI_ES %ip_&name&_dls
  485.     ROUTE_FIND_in_AX_BX_CX_out_AX_DL_const_BP_ES %ip_&name&_router, forme, drop_route
  486.     mov word ptr ip_write_gate, AX
  487.  
  488.     mov SI, BP                                      ;; restore pointer
  489.     IP_DEC_TTL_in_SI_ES_const_BX_CX_DX_BP_SI_DI_ES drop_ttl
  490.  
  491.     xor DH, DH                              ;; set up jump to proper DL
  492.     shl DX, 1
  493.     mov DI, offset jmp_table
  494.     add DI, DX
  495.  
  496.     jmp [DI]                                ;; jump to proper DL
  497.  
  498.         ;; the above jump goes to one of the code fragments below
  499.     IRP idx, <1,2,3,4,5,6,7,8>
  500.     if idx le ip_&name&_dls 
  501.         IP_INIT_DL_LABEL name, idx, read_dl&_write_start
  502.  
  503.         if idx eq read_dl
  504.             mov word ptr ip_write_sav_seg, ES
  505.         endif
  506.         IP_DL_TEST_BROAD_in_AX idx, drop
  507.  
  508.         mov BP, word ptr ip_write_sav
  509.         IP_SEND_PACKET_in_BP_ES name, read_dl, idx, ip_write_gate
  510.  
  511.         if idx eq read_dl
  512.             IP_DL_TEST_FLAGS idx, NO_REDIRECT
  513.             jnz drop
  514.  
  515.             mov SI, word ptr ip_write_sav
  516.             mov ES, word ptr ip_write_sav_seg
  517.  
  518.             IP_DL_ADDRESS_out_AX_const_BX_CX_DX_BP_SI_DI idx
  519.             mov BX, word ptr ip_write_gate
  520.             jmp redirect
  521.         else
  522.             jmp drop
  523.         endif
  524.     endif
  525.     endm
  526.         ;; the above code does NOT fall through
  527.  
  528.     drop_route:
  529.         mov SI, BP
  530.         ICMP_ERROR_in_SI_ES %ip_&name&_icmp, ICMP_UNREACHABLE, ICMP_UNREACH_HOST, name
  531.         jmp drop
  532.     redirect:
  533.         ICMP_REDIRECT_in_AX_BX_SI_ES %ip_&name&_icmp, ICMP_REDIRECT_HOST, name
  534.         jmp drop
  535.     drop_ttl:
  536.         ICMP_ERROR_in_SI_ES %ip_&name&_icmp, ICMP_TIME, ICMP_TIME_TTL, name
  537.         jmp drop
  538.     broad_forme:
  539.         mov ip_&name&_data.ip_broadcast, 1
  540.         jmp continue_forme
  541.     forme:
  542.         mov ip_&name&_data.ip_broadcast, 0
  543.     continue_forme:
  544.         mov BX, ip_write_sav
  545.         mov CX, ip_write_size
  546.         DL_IP_R_CONT_in_BX_CX_ES_const_BX_CX_DX_BP_SI_DI_ES read_dl, ip_ok
  547.             mov SI, BX
  548.             mov DI, offset ip_&name&_data.ip_packet
  549.             mov DX, DS
  550.             mov ES, DX
  551.             DL_IP_COPY_in_CX_SI_DI_ES_out_SI_DI_const_BX_BP_ES read_dl
  552.             mov BX, offset ip_&name&_data.ip_packet
  553.             mov CX, ip_write_size
  554.         ip_ok:
  555.         CALL ip_&name&_read_packet
  556.     drop:
  557. ENDM
  558.  
  559. ;; this macro simply returns the first two bytes of IP address of 'mydl'
  560. IP_DL_ADDRESS_out_AX_const_BX_CX_DX_BP_SI_DI MACRO mydl
  561.  
  562.     mov AX, word ptr dl_ip_&mydl&_ip
  563. ENDM
  564.  
  565. ;; this macro tests if the flag bit 'mybit' of the DL_IP 'name' is set
  566. IP_DL_TEST_FLAGS MACRO name, mybit
  567.     test dl_ip_&name&_flags, mybit
  568. ENDM
  569.  
  570. ;; This macro tests if the dest AX should be droped because it is a broadcast
  571. IP_DL_TEST_BROAD_in_AX MACRO name, drop
  572.     local forward
  573.  
  574.     cmp AX, word ptr dl_ip_&name&_broad+2               ;; should we forward
  575.     jnz forward
  576.     test dl_ip_&name&_flags, NO_DIR_BROAD
  577.     jnz drop
  578.     forward:
  579. ENDM
  580.  
  581.  
  582. ;;*****************************************************************************
  583. ;;  IP_INIT_DL_LABEL generates a code lable for use in a jump table for
  584. ;;  'name', 'dl'.  'suffix' is a unique suffix
  585. ;;
  586. IP_INIT_DL_LABEL MACRO name, dl, suffix
  587.     ip_&name&_dl_&dl&_&suffix:
  588. ENDM
  589.  
  590. ;;*****************************************************************************
  591. ;;  IP_INIT_DL_JMP_TAB generates the table entry for the entry 'name', 'dl'
  592. ;;  'suffix' is a unique suffix.
  593. ;;  This is meant for use in a .DATA section 
  594. ;;
  595. IP_INIT_DL_JMP_TAB MACRO name, dl, suffix
  596.     dw ip_&name&_dl_&dl&_&suffix
  597. ENDM
  598.  
  599.  
  600. ;;****************************************************************************
  601. ;; IP_SEND_PACKET sends the packet pointed to by BP:ES of from the
  602. ;; DL 'read_dl' to the dl 'write_dl'.  'gate' is an address that contains
  603. ;; the last two bytes of the IP address.  This is the routine that handles 
  604. ;; IP fragmentation
  605. ;;
  606. IP_SEND_PACKET_in_BP_ES MACRO name, read_dl, write_dl, gate
  607.     local done, frag_loop, size_ok, fragment, ip_head_len
  608.  
  609.     .DATA
  610.     ip_head_len     DW ?
  611.     .CODE
  612.  
  613.     mov CX, ES:[BP+ip_length]
  614.     xchg CH, CL
  615.     if dl_ip_&read_dl&_mtu gt dl_ip_&write_dl&_mtu  ;;is fragmenting EVER needed
  616.     cmp CX, dl_ip_&write_dl&_mtu
  617.     ja fragment
  618.     endif
  619.         DL_IP_W_ACCESS_in_CX_out_DI_ES_const_CX_BP write_dl, done
  620.  
  621.         mov SI, BP                      ;; restore SI
  622.         mov BX, CX                      ;; save CX
  623.         DL_IP_COPY_in_CX_SI_DI_ES_out_SI_DI_const_BX_BP_ES read_dl
  624.         mov CX, BX                      ;; restore CX
  625.  
  626.         mov AX, word ptr gate
  627.         DL_IP_W_WRITE_in_AX_CX_const_BP write_dl
  628.  
  629.     if dl_ip_&read_dl&_mtu gt dl_ip_&write_dl&_mtu  ;;is fragmenting EVER needed
  630.         jmp done
  631.     fragment:
  632.         test byte ptr ES:[SI+ip_frag], SWAPPED_IP_DONT_FRAG   ;; OK to fragment?
  633.         jnz done
  634.  
  635.             ;; compute the header size
  636.         xor CX, CX          ;; make CX hold the size of the IP header
  637.         mov CL, ES:[BP+ip_ver_size]
  638.         and CL, 0FH
  639.         shl CL, 1
  640.         shl CL, 1           
  641.         mov word ptr ip_head_len, CX
  642.  
  643.         mov AX, DS          ;; copy the header
  644.         mov ES, AX
  645.         mov SI, BP
  646.         mov DI, offset ip_&name&_data.ip_header
  647.         DL_IP_COPY_in_CX_SI_DI_ES_out_SI_DI_const_BX_BP_ES read_dl
  648.         mov BP, SI          ;; save SI
  649.  
  650.             ;; fix checksum so it is correct when ip_frag = ip_len = 0
  651.         mov AX, word ptr ip_&name&_data.ip_header.ip_check      
  652.         add AX, word ptr ip_&name&_data.ip_header.ip_frag
  653.         adc AX, word ptr ip_&name&_data.ip_header.ip_length
  654.         adc AX, 0
  655.         mov word ptr ip_&name&_data.ip_header.ip_check, AX
  656.  
  657.         frag_loop:
  658.             mov CX, dl_ip_&write_dl&_mtu            ;; ask for biggest buffer
  659.             DL_IP_W_ACCESS_in_CX_out_DI_ES_const_CX_BP write_dl, done
  660.  
  661.             mov DX, word ptr ip_head_len        ;; copy the header
  662.             mov CX, DX
  663.             mov SI, offset ip_&name&_data.ip_header
  664.             shr CX, 1
  665.             rep
  666.             movsw
  667.             sub DI, DX              ;; make DI point to begining of the packet 
  668.  
  669.             mov AX, word ptr ES:[DI+ip_frag]
  670.             xchg AH, AL
  671.             mov CX, word ptr ES:[DI+ip_length]
  672.             xchg CH, CL
  673.             cmp CX, dl_ip_&write_dl&_mtu                    ;; can we send it
  674.             jbe size_ok
  675.                 mov CX, dl_ip_&write_dl&_mtu
  676.                 sub CX, DX              ;; subtract the IP header length
  677.                 and CX, 0FFF8H          ;; make multiple of 8
  678.                 add CX, DX              ;; add the IP header length
  679.                 or AX,  IP_MORE_FRAG    ;; indicate not the last
  680.             size_ok:
  681.             xchg CH, CL
  682.             mov word ptr ES:[DI+ip_length], CX
  683.             xchg AH, AL
  684.             mov word ptr ES:[DI+ip_frag], AX
  685.  
  686.             mov BX, word ptr ES:[DI+ip_check]       ;; fix up checksum
  687.             sub BX, CX
  688.             sbb BX, AX
  689.             sbb BX, 0
  690.             mov word ptr ES:[DI+ip_check], BX
  691.  
  692.                 ;; set up stuff for next round
  693.             xchg CH, CL
  694.             sub CX, DX                  ;; subtract the IP header length
  695.             mov BX, CX
  696.             shr BX, 1
  697.             shr BX, 1
  698.             shr BX, 1
  699.             mov AX, word ptr ip_&name&_data.ip_header.ip_frag
  700.             xchg AH, AL
  701.             add AX, BX
  702.             xchg AH, AL
  703.             mov word ptr ip_&name&_data.ip_header.ip_frag, AX
  704.  
  705.             mov BX, word ptr ip_&name&_data.ip_header.ip_length
  706.             xchg BH, BL
  707.             sub BX, CX
  708.             xchg BH, BL
  709.             mov word ptr ip_&name&_data.ip_header.ip_length, BX
  710.  
  711.             mov SI, BP                      ;; restore SI
  712.             add DI, DX                      ;; restore DI
  713.             mov BX, CX
  714.             add BX, DX                      ;; BX holds total Lenght
  715.             DL_IP_COPY_in_CX_SI_DI_ES_out_SI_DI_const_BX_BP_ES read_dl
  716.             mov BP, SI                      ;; save SI
  717.  
  718.             mov AX, word ptr gate
  719.             mov CX, BX
  720.             DL_IP_W_WRITE_in_AX_CX_const_BP write_dl
  721.  
  722.             mov BX, word ptr ip_&name&_data.ip_header.ip_length
  723.             xchg BH, BL
  724.             cmp BX, word ptr ip_head_len
  725.         ja frag_loop
  726.     endif
  727.     done:
  728. ENDM
  729.  
  730.  
  731. ;;******************************************************************************
  732. ;; IP_DEC_TTL_in_BX_ES
  733. ;;      IP_DEC_TTL  decrements the TTL of the IP packet pointed to by SI:ES
  734. ;;      and jumps to 'drop' if the TTL has expired.
  735. ;;
  736. IP_DEC_TTL_in_SI_ES_const_BX_CX_DX_BP_SI_DI_ES MACRO drop
  737.     mov AL, byte ptr ES:[SI+ip_ttl]             ;; decrement ttl
  738.     sub AL, 01                                  ;; can't use dec (need carry)
  739.     jbe drop
  740.     mov byte ptr ES:[SI+ip_ttl], AL
  741.     mov AX, word ptr ES:[SI+ip_check]           ;; fix up checksum
  742.     add AX, 1                                   ;; add 1 in 1's complement
  743.     adc AX, 0 
  744.     mov word ptr ES:[SI+ip_check], AX
  745. ENDM
  746.  
  747.  
  748. ;;******************************************************************************
  749. ;;    IP_COMPUTE_NET
  750. ;;      IP_COMPUTE_NET takes an IP address in AX,BX  and given the ip address 
  751. ;;      and the dl list 1..dls and computes the network part of the IP address
  752. ;;      and returns it in AX,BX.  
  753. ;;
  754. IP_COMPUTE_NET_in_AX_BX_out_AX_BX_const_CX_DX_BP_SI_DI_ES MACRO dls
  755.     local done
  756.     .errb <dls>
  757.  
  758.     IRP idx, <8,7,6,5,4,3,2,1>  
  759.     if idx le dls
  760.         IP_CHECK_SUBNET_in_AX_BX_out_AX_BX_const_CX_DX_BP_SI_DI_ES idx, done
  761.     endif
  762.     endm
  763.  
  764.     IP_COMP_NET_in_AX_BX_out_AX_BX_const_CX_DX_BP_SI_DI_ES dls
  765.     done:
  766. ENDM
  767.  
  768. ;;******************************************************************************
  769. ;; IP_COMP_NET is like IP_COMPUTE_NET but it does its computation based ONLY
  770. ;; on the Class of the IP address (No subnet checking
  771. ;;
  772. IP_COMP_NET_in_AX_BX_out_AX_BX_const_CX_DX_BP_SI_DI_ES MACRO dls
  773.     local class_A, class_B, class_C 
  774.  
  775.     test AL, 80h        ;; normal IP network interpretation
  776.     jz class_A
  777.     test AL, 40h
  778.     jz class_B
  779.     jmp class_C
  780.  
  781.     class_A:
  782.         xor AH, AH
  783.     class_B:
  784.         xor BL, BL
  785.     class_C:
  786.         xor BH, BH
  787. ENDM
  788.  
  789.  
  790. ;;******************************************************************************
  791. ;; IP_CHECK_SUBNET
  792. ;;   Check_subnet checks if the IP address in AX,BX matches the subnet of 
  793. ;;   the Data link interface 'dl'.  If it does, it computes the network part
  794. ;;   and returns it in AX,BX and then jumps to 'success'
  795. ;;
  796. IP_CHECK_SUBNET_in_AX_BX_out_AX_BX_const_CX_DX_BP_SI_DI_ES MACRO dl, success
  797.     local fail, mask_it
  798.     .errb <success>
  799.  
  800.     cmp AL, byte ptr dl_ip_&dl&_ip
  801.     jnz fail
  802.     test AL, 80H
  803.     jz mask_it
  804.     cmp AH, byte ptr dl_ip_&dl&_ip+1
  805.     jnz fail
  806.     test AL, 40H
  807.     jz mask_it
  808.     cmp BL, byte ptr dl_ip_&dl&_ip+2
  809.     jnz fail
  810.  
  811.     mask_it:
  812.         and BX, word ptr dl_ip_&dl&_mask+2
  813.         jmp success
  814.     fail:
  815. ENDM
  816.  
  817.  
  818. ;;*****************************************************************************
  819. ;; IP_PACKET_in_BX_ES name
  820. ;;      IP_PACKET_in_BX_ES does all the proessing of a packet that is destined
  821. ;;      for this node.  BX:ES points to the begining of the IP packet. 
  822. ;;      AX holds the hardware protocol number and CX holds the length of 
  823. ;;      the packet.
  824. ;;      Basicly this routine just dispatches it to the proper READ routine
  825. ;;
  826. IP_PACKET_in_AX_BX_CX_ES MACRO name
  827.     local drop
  828.     .errb <name>
  829.  
  830.     test word ptr ES:[BX+ip_frag], 3FFFH        ;; if fragmented
  831.     jnz drop
  832.  
  833.     xor AH, AH
  834.     mov AL, byte ptr ES:[BX+ip_proto]                   ;; load protocol
  835.     mov word ptr ip_&name&_data.ip_read_head, BX        ;; save header pointer
  836.     xor DX, DX                              ;; compute the size of the header
  837.     mov DL, ES:[BX+ip_ver_size]
  838.     and DL, 0FH
  839.     shl DX, 1
  840.     shl DX, 1
  841.     sub CX, DX
  842.     add BX, DX
  843.  
  844.     mov DX, AX                              ;; jump to proper routine
  845.     and DL, 1FH
  846.     shl DX, 1
  847.     mov SI, offset ip_&name&_data.ip_read_jmp
  848.     add SI, DX
  849.     jmp [SI]                                ;; note this is NOT a call,
  850.                                             ;; so when the code returns
  851.                                             ;; it will return to the caller
  852.                                             ;; of this routine
  853.  
  854.     drop:
  855. ENDM
  856.  
  857.  
  858. ;;*****************************************************************************
  859. ;; IP_ASCII_in_SI_DI_ES_out_DI converts the IP address stored at SI:DS
  860. ;; to ASCII dot notation in the buffer ENDING at DI:ES.  DI:ES returns the 
  861. ;; begining of the string generated.
  862. ;;
  863. IP_ASCII_in_SI_DI_ES_out_DI_const_BX_BP_ES MACRO 
  864.     local ip_loop, ip_loop_done
  865.  
  866.     std                                     ;; count down
  867.     mov CX, 4
  868.     add SI, 3
  869.     dec DI
  870.     ip_loop:
  871.         lodsb 
  872.         TO_ASCII_in_AL_DI_ES_out_DI_const_BX_CX_BP_SI_ES 
  873.         dec CX
  874.         jz ip_loop_done
  875.         mov AL, '.'
  876.         stosb
  877.     jmp ip_loop
  878.     ip_loop_done:
  879.     inc DI
  880.     cld                                     ;; count up again
  881. ENDM
  882.  
  883.  
  884. ;;*****************************************************************************
  885. ;; TO_ASCII converts the number in AL to ascii (decimal) and puts the resulting
  886. ;; string in the buffer whose END is pointed to by DI:ES.  DI points to the 
  887. ;; BEGINING of the string when it is done.  THIS ROUTINE ASSUMES THE DIRECTION
  888. ;; FLAG IS COUNTING DOWN
  889. ;;
  890. TO_ASCII_in_AL_DI_ES_out_DI_const_BX_CX_BP_SI_ES MACRO
  891.     local loop_write
  892.  
  893.     mov DL, 10
  894.     loop_write:            ;; write in the number
  895.         xor AH, AH
  896.         idiv DL            ;; AH = AL % 10      AL = AL / 10
  897.         xchg AL, AH
  898.         add AL, 48          ;; add ascii '0'
  899.         stosb
  900.         mov AL, AH
  901.         and AL, AL
  902.     jnz loop_write
  903. ENDM
  904.