	TITLE   support

	.386

_BSS	segment dword public use32 'BSS'
dop	dd	?
bop	db	?
_BSS	ends

DGROUP	group _BSS

	ASSUME	cs:_TEXT, ds:DGROUP, es:nothing, ss:nothing

_TEXT	segment	dword public use32 'CODE'
		align	4
;
; u_short near iphcheck(ptr)
; struct iph *ptr;
;
;	Internet header checksum
;	header checksum is calculated for a higher level program to verify
;

	PUBLIC	iphcheck_
iphcheck_ proc	near
	push	esi
	mov	esi,eax
	push	ebx
	xor	ebx,ebx
	lodsd
	mov	ebx,eax
	lodsd
	add	ebx,eax
	lodsd
	adc	ebx,eax
	lodsd
	adc	ebx,eax
	lodsd
	adc	ebx,eax
	adc	ebx,0
	mov	eax,ebx
	shr	eax,16
	add	ax,bx
	adc	ax,0
	cmp	ax,-1
	jz	short L3
	not	eax		; take one more 1-complement
L3:
	pop	ebx
	pop	esi
	ret
iphcheck_	ENDP

	PUBLIC	ipcheck_
; u_short ipcheck(ptr, len)
; struct iph _Far *ptr;		EDX:EAX
; u_int len;			EBX

ipcheck_	PROC NEAR
	push	ecx
	push	esi
	push	ds
	mov	ecx,ebx		; len
	mov	esi,eax		; ptr
	mov	ds,dx		; FP_SEG(ptr)

	shrd	ebx,ecx,2
	shr	ecx,2		; len = len / 4
	sub	edx,edx		; also clears carry
chksum:
	lodsd
	adc	edx,eax		; keep adding
	loop	chksum		; til' done

	adc	edx,ecx		; adds the carry bit in

	mov	eax,ecx		; eax = 0;
	shld	ecx,ebx,2
	jecxz	short done

	not	eax
	shl	ecx,3
	shl	eax,cl
	not	eax
	and	eax,[esi]
	add	edx,eax
	adc	edx,0

done:
	mov	eax,edx
	shr	eax,16
	add	ax,dx
	adc	ax,0

	cmp	ax,-1
	jz	short L1
	not	eax		; take one more 1-complement
L1:

	pop	ds
	pop	esi
	pop	ecx
	ret
ipcheck_	ENDP

	PUBLIC	tcpcheck_
; u_short near tcpcheck(psptr, tcpptr, tcplen)
; struct pseudotcp *psptr;	/* eax */
; struct tcph Far *tcpptr;	/* ecx, ebx */
; u_int tcplen;			/* edx */
;
;  TCP checksum
;
tcpcheck_	proc	near
        push	esi
	push	ds
	push	eax		; save psptr

	mov	esi,ebx
	mov	ds,cx
	mov	ecx,edx		; count
	shr	ecx,1		; divide by two, round down

	sub	ebx,ebx           ; clear to begin
rchksum:
	lodsw
	adc	bx,ax		; add to running sum
	loop	rchksum
	adc	bx,cx
				; don't modify CF until the adc instruction
	bt	edx,0
	jnc	notodd
	lodsb			; get that last byte
	mov	ah,ch		; clear the high portion
	add	bx,ax		; add the last one in
				; don't modify CF until the adc instruction
notodd:
	pop	esi		; restore psptr
	pop	ds
	mov	ecx,6		; length of p-hdr in words
pchksum:
	lodsw			; get next word
	adc	bx,ax		; keep adding
	loop	pchksum		; til' done
	adc	bx,0		; adds the carry bit in

	cmp	bx,-1
	jz	L2
	not	bx		; take one more 1-complement
L2:
	movzx	eax,bx
	pop	esi
	ret
tcpcheck_	endp

_TEXT	ends
	end
