home *** CD-ROM | disk | FTP | other *** search
- ;;*************************************************************************
- ;; udp.inc udp.inc
- ;;*************************************************************************
- ;;
- ;; Copyright (C) 1989 Northwestern University, Vance Morrison
- ;;
- ;;
- ;; Permission to view, compile, and modify for LOCAL (intra-organization)
- ;; USE ONLY is hereby granted, provided that this copyright and permission
- ;; notice appear on all copies. Any other use by permission only.
- ;;
- ;; Northwestern University makes no representations about the suitability
- ;; of this software for any purpose. It is provided "as is" without expressed
- ;; or implied warranty. See the copywrite notice file for complete details.
- ;;
- ;;*****************************************************************************
- ;;
- ;; Routines provided by this module
- ;;
- ;; UDP_DECLARE name, net, icmp
- ;; UDP_DEFINE name
- ;; UDP_SOCK_DEFINE name, udp, port, code_label
- ;;
- ;; Variables Provided by this Module (READ ONLY!!!)
- ;;
- ;;
- ;;*****************************************************************************
- ;; definition of User datagram prococol packet header structure
- ;;
- udp STRUC
- udp_src DW ?
- udp_dst DW ?
- udp_length DW ?
- udp_check DW ?
- udp ENDS
-
- UDP_PROTO = 17
-
- ;;****************************************************************************
- ;; data needed by this module
- ;;
- udp_jmp_entry STRUC
- udp_read_port DW ?
- udp_read_label DW ?
- udp_jmp_entry ENDS
-
- udp_data STRUC
- udp_read_cnt DW 0
- udp_read_jmp udp_jmp_entry 32 DUP (<>)
- udp_data ENDS
-
- udp_sock_data STRUC
- udp_write_off DW ?
- udp_write_seg DW ?
- udp_write_dst DW ?
- udp_sock_data ENDS
-
-
- ;;******************************************************************************
- ;; UDP_DECLARE name, net, icmp
- ;; UDP_DECLARE declares
- ;;
- UDP_DECLARE MACRO name, net, icmp
- .errb <icmp>
-
- .DATA
- udp_&name&_net = net
- udp_&name&_icmp = icmp
- global udp_&name&_data:udp_data
- .CODE
- global udp_&name&_read_drop:near
- ENDM
-
-
- ;;*****************************************************************************
- ;; UDP_DEFINE name
- ;; UDP_DECLARE
- ;;
- UDP_DEFINE MACRO name
- local around, udp_read, skip
- .errb <name>
-
- .DATA
- udp_&name&_data udp_data <>
-
- .CODE
- jmp around
- udp_read:
- UDP_PACKET_in_AX_BX_CX_ES name
- RET
-
- udp_&name&_read_drop:
- IP_R_BROAD_const_AX_BX_CX_DX_BP_SI_DI_ES %udp_&name&_net, skip
- IP_R_HEADER_in_ES_out_SI_const_BX_CX_DX_BP_DI_ES %udp_&name&_net
- ICMP_ERROR_in_SI_ES %udp_&name&_icmp, ICMP_UNREACHABLE, ICMP_UNREACH_PORT, %udp_&name&_net
- skip:
- RET
- around:
- IP_R_READ %udp_&name&_net, UDP_PROTO, udp_read
- ENDM
-
-
- ;;*****************************************************************************
- UDP_SOCK_DECLARE MACRO name, udp, port
- .errb <port>
-
- .DATA
- udp_sock_&name&_udp = udp
- udp_sock_&name&_port = ((port mod 256)*256 + (port/256))
- udp_sock_&name&_net = udp_&udp&_net
- global udp_sock_&name&_data:udp_sock_data
- .CODE
- ENDM
-
-
- ;;*****************************************************************************
- ;;
- UDP_SOCK_DEFINE MACRO name, code_label
- .errb <code_label>
-
- .DATA
- udp_sock_&name&_data udp_sock_data <>
-
- .CODE
- UDP_R_READ %udp_sock_&name&_udp, %udp_sock_&name&_port, code_label
- ENDM
-
-
- ;;*****************************************************************************
- ;; UDP_R_SRC_in_SI_ES_out_AX_BX_CX name
- ;; UDP_R_SRC returns the source port of the UDP data packet pointed to
- ;; by SI:ES that was given to the UDP_R_READ routine. The IP address
- ;; is put in AX,BX and the port number in CX
- ;;
- UDP_SOCK_R_SRC_in_SI_ES_out_AX_BX_CX_const_DX_BP_SI_DI_ES MACRO name
- .errb <name>
-
- sub SI, (size udp)
- IP_R_SRC_in_ES_out_AX_BX_const_CX_DX_BP_SI_DI_ES %udp_sock_&name&_net
- mov CX, word ptr ES:[SI+udp_src]
- xchg CH, CL
- add SI, (size udp)
- ENDM
-
-
- ;;*****************************************************************************
- ;; UDP_SOCK_W_ACCESS_in_AX_BX_CX_DX_out_AX_DI_ES name
- ;; UDP_SOCK_W_ACCESS retrieves a write buffer for a UDP packet data.
- ;; AX,BX holds the destination IP address of the packet and DX holds
- ;; the destination port for the packet. The output buffer is returned
- ;; in DI:ES. UDP_W_ACCESS returns a status code in AX that is 0 if
- ;; the access was successful If the length is greater than the MTU
- ;; of the interface this routine fails. (thus the maximum guarenteed
- ;; length is dl_ip_min_mtu)
- ;;
- UDP_SOCK_W_ACCESS_in_AX_BX_CX_DX_out_AX_DI_ES MACRO name
- .errb <fail>
-
- xchg DH, DL
- mov udp_sock_&name&_data.udp_write_dst, DX ;; save the destination
- mov DL, UDP_PROTO
- add CX, size udp
- IP_W_ACCESS_in_AX_BX_CX_DL_out_AX_DI_ES %udp_sock_&name&_net
- mov udp_sock_&name&_data.udp_write_off, DI
- mov udp_sock_&name&_data.udp_write_seg, ES
- add DI, size udp
- ENDM
-
-
- ;;*****************************************************************************
- ;; UDP_SOCK_W_WRITE_in_CX name
- ;; UDP_SOCK_W_WRITE tells the UDP interface to send the PACKET that is been
- ;; loaded into the buffer DI:ES. The length of the packet is in CX
- ;; note that this UDP level does NOT support fragmentation, so CX better
- ;; be less than the MTU of the interface (~1500 for ethernet)
- ;;
- UDP_SOCK_W_WRITE_in_CX MACRO name
- .errb <name>
-
- les DI, dword ptr udp_sock_&name&_data.udp_write_off
- add CX, size udp
- xchg CH, CL
- mov ES:[DI+udp_length], CX
- xchg CH, CL
- mov word ptr ES:[DI+udp_check], 0
- mov AX, udp_sock_&name&_data.udp_write_dst
- mov ES:[DI+udp_dst], AX
- mov AX, udp_sock_&name&_port
- mov ES:[DI+udp_src], AX
-
- mov DX, CX
- xchg DH, DL
- IP_GET_SRC_out_AX_BX_const_CX_DX_BP_SI_DI_ES %udp_sock_&name&_net
- add DX, AX
- adc DX, BX
- IP_GET_DST_out_AX_BX_const_CX_DX_BP_SI_DI_ES %udp_sock_&name&_net
- adc DX, AX
- adc DX, BX
- mov AL, 0
- mov AH, UDP_PROTO
- adc DX, AX
- adc DX, 0 ;; add in the last carry if any
- mov SI, DI
- mov BX, DX
- mov DX, CX ;; save CX
- UDP_COMPUTE_CHECK_in_BX_CX_SI_ES_out_BX_const_DX_BP_DI_ES
- mov word ptr ES:[DI+udp_check], BX
- mov CX, DX ;; restore CX
-
- IP_W_WRITE_in_CX %udp_sock_&name&_net
- ENDM
-
-
- ;;*****************************************************************************
- ;; UDP_R_READ name, port, code_label
- ;; UDP_READ declares that the code starting at 'code_label' should
- ;; be called when a UDP packet for port 'port' is read in
- ;; The data in the UDP packet is passed to the object in BX:ES the
- ;; port number in AX and the length of the data in CX.
- ;; If the source address is requires UDP_R_SRC should be called
- ;;
- UDP_R_READ MACRO name, port, code_label
- local skip
- .errb <code_label>
-
- push DX
- push DI
- mov DX, word ptr udp_&name&_data.udp_read_cnt
- cmp DX, 32
- jge skip
- mov DI, DX
- inc DX
- mov word ptr udp_&name&_data.udp_read_cnt, DX
- shl DI, 1
- shl DI, 1
- add DI, offset udp_&name&_data.udp_read_jmp
- mov word ptr [DI+udp_read_port], port
- mov word ptr [DI+udp_read_label], offset code_label
- skip:
- pop DI
- pop DX
- ENDM
-
-
- ;;*****************************************************************************
- ;; UDP_PACKET_in_AX_BX_CX_ES name
- ;; UDP_PACKET_in_BX_ES does all the proessing of a packet that is destined
- ;; for this node. BX:ES points to the begining of the data in the UDP
- ;; packet. CX holds the length. AX holds the protocol number.
- ;; Basicly this routine just dispatches it to the proper READ routine.
- ;;
- UDP_PACKET_in_AX_BX_CX_ES MACRO name
- local continue, valid, no_checksum, loop, found, not_found
-
- cmp AL, UDP_PROTO
- je continue
- ret
- continue:
- mov DX, word ptr ES:[BX+udp_check]
- or DX, DX
- jz no_checksum
- mov BP, BX ;; save BX
- mov BX, AX
- xchg BH, BL
- IP_R_HEADER_in_ES_out_SI_const_BX_CX_DX_BP_DI_ES %udp_&name&_net
- add BX, word ptr ES:[SI+ip_src]
- adc BX, word ptr ES:[SI+ip_src+2]
- adc BX, word ptr ES:[SI+ip_dst]
- adc BX, word ptr ES:[SI+ip_dst+2]
- xchg CH, CL
- adc BX, CX
- xchg CH, CL
- adc BX, 0 ;; add in the last carry if any
- mov word ptr ES:[BP+udp_check], 0 ;; prepare for checksum calculation
- mov SI, BP
- UDP_COMPUTE_CHECK_in_BX_CX_SI_ES_out_BX_const_DX_BP_DI_ES
- cmp DX, BX
- je valid
- ret
- valid:
- mov BX, BP
- mov word ptr ES:[BX+udp_check], DX ;; restore checksum
-
- no_checksum:
- mov AX, word ptr ES:[BX+udp_dst] ;; dest_socket
- mov CX, word ptr ES:[BX+udp_length] ;; load length
- xchg CH, CL
- sub CX, size udp
- add BX, size udp
-
- ;; jump to proper routine
- mov DX, word ptr udp_&name&_data.udp_read_cnt
- inc DX
- mov SI, offset udp_&name&_data.udp_read_jmp
-
- loop:
- dec DX
- jz not_found
- cmp word ptr [SI+udp_read_port], AX ;; compare port number
- je found
- add SI, (size udp_jmp_entry)
- jmp loop
-
- not_found:
- jmp udp_&name&_read_drop
-
- found:
- jmp word ptr [SI+udp_read_label] ;; Note this is a jump, thus
- ;; when the callie returns it
- ;; will return to the caller of
- ;; this routine
- ENDM
-
- ;;*****************************************************************************
- UDP_COMPUTE_CHECK_in_BX_CX_SI_ES_out_BX_const_DX_BP_DI_ES MACRO
- local check_loop, done, not_zero
-
- shr CX, 1
- pushf
- clc
- check_loop:
- seges
- lodsw
- adc BX, AX
- loop check_loop
- adc BX, 0 ;; add in the last carry if any
- popf
- jnc done
- xor AX, AX ;; odd number of bytes
- mov AL, byte ptr ES:[SI]
- add BX, AX
- adc BX, 0 ;; add in the last carry if any
- done:
- xor BX, 0FFFFH
- jnz not_zero
- not BX
- not_zero:
- ENDM
-