Category : Network Files
Archive   : PDCLK145.ZIP
Filename : PING.ASM

 
Output of file : PING.ASM contained in archive : PDCLK145.ZIP
; ping.asm
;========================================================================

; Copyright (C) 1991 by [email protected], see file COPYING.

MsgEchoHead db CR, LF, "Ping with packet size "
MsgEchoSweep db " "
MsgEchoSize db "0 and interval"
MsgEchoMs db " 0 ms to "
MsgEchoTarget db "1.2.3.4 :", CR, LF, LF
MsgEchoStats db "ÄÄÄÄÄÄÄÄÄ Packets ÄÄÄÄÄÄÄÄ º ÄÄÄÄÄÄ Delay ms ÄÄÄÄÄÄ º Packet º Load º Time ", CR, LF
db "transmit receive diff º this min avg max º loss º kb/s º s ", CR, LF, "$$"
MsgEcho db " 0 0 0 0 0 0 0 0.0000 % 0 0 ", CR, '$'

MsgSerrTbl dw offset MsgSerrUnr
dw offset MsgSerrObuf
dw offset MsgSerrNoarp
dw offset MsgSerrTimout
dw offset MsgSerrNotraf
SERRTABLEN equ $-MsgSerrTbl
dw offset MsgSerrUnimpl

MsgSerrUnr db LF, "Host or net unreachable", CR, LF, '$'
MsgSerrObuf db LF, "Temporary out of buffers", CR, LF, '$'
MsgSerrNoarp db LF, "Got no ARP reply", CR, LF, '$'
MsgSerrTimout db LF, "Timeout", CR, LF, '$'
MsgSerrNotraf db LF, "Received no traffic from destination", CR, LF, '$'

MsgSerrUnimpl db LF, "Send Error.", CR, LF, '$'
even
EchoTarget dw 0, 0 ; echo argument values
EchoSize dw 32
EchoInterval dw 256
EchoData dw 101h
EchoDataIncW dw 1

EchoStart dw 0, 0, 0 ; echo variables
EchoNext dw 0
EchoLastDispl dw 0
EchoLastHi dw 0
EchoMaxSize dw 1500
EchoAvgSum dw 0, 0
EchoFudge dw 0
EchoLoad dw 0, 0
EchoPrevLoad dw 0, 0
EchoDrop dw 0
EchoLastErr dw 0
PingRowCnt dw 17
k55 dw 55
k100 dw 100
k220 dw 220

EchoTx32 dw 0, 0 ; echo display variables
EchoRx32 dw 0, 0
EchoDif dw 0, 0
EchoThis dw 0
EchoMin dw 0ffffh
EchoAvg dw 0
EchoMax dw 0
EchoLoss dw 0, 0
EchoElapsed dw 0, 0


;************************************************************************
;* EchoAwhile
;************************************************************************

MsgCalling db "Calling nameserver(s)... $"
MsgNameRep db "got reply in "
MsgNameRepTim db " ms.", CR, LF, '$'
MsgBadName db LF, "Bad hostname (or no nameserver).$"

EchoAwhile proc near
cmp EchoTarget,0 ; want to ping someone?
jne EchoYes
ret
EchoYes:
call InitTimer ; prepare millisecond timing

call HardwareTicks
mov EchoStart,si ; note start ticks
mov EchoStart+2,dx
mov EchoStart+4,ax

call DblShrX
mov EchoNext,ax

cmp EchoTarget,127 ; dns lookup to do?
jne EchoIpAddr

mov dx,offset MsgCalling
mov ah,9
int 21h

mov dx,2345h ; ping udp src port
xor ax,ax ; NsId
mov si,offset EchoNameBuf ; Ns question string

call NsResolve ; call nameserver(s)

call HardwareTicks ; response time
sub ax,EchoStart+4
sbb dx,EchoStart+2
div kTimerScale
mov di,offset MsgNameRepTim
mov PutNumFiller,' '
mov PutMinDigits,4
call PutNum

mov dx,offset MsgNameRep ; display it.
mov ah,9
int 21h

cmp EchoTarget,127 ; name resolved?
jne EchoIpAddr

mov dx,offset MsgBadName
mov ah,9
int 21h
EchoErrTerm:
mov al,'e'-'0'
call terminate

EchoIpAddr:
test ArgFlags,MAKE_TABLE
jz EchoNotTbl
or GenFlags,TBL_READY
EchoNotTbl:
mov di,offset EchoSizeVec
mov cx,(EchoSizeEnd-EchoSizeVec)/2
xor ax,ax
rep stosw

test ArgFlags,TERM_WAIT
jnz EchoAsIs
cmp EchoInterval,128
jge EchoAsIs
mov EchoInterval,128
EchoAsIs:
call BufAlloc ; get a send buf
jz EchoErrTerm

call MakeSendDescr
mov [di].uIcmpTypeCode,8 ; type = echo request
test GenFlags,UDP_ECHO
jz EchoUseIcmp

mov word ptr MsgEchoHead+2,'cE'
mov word ptr MsgEchoHead+4,'oh'
mov word ptr [di].uUdpSrc,0703h ; my udp echo port
mov word ptr [di].uUdpDst,0900h ; dst discard port
test ArgFlags,UDP_DISCARD
jnz EchoUseIcmp
mov word ptr [di].uUdpDst,0700h ; dst echo port
EchoUseIcmp:
mov cx,(1500-IPHDRLEN-ICMPHDRLEN-4)/2
add di,ICMPHDRLEN+4
mov ax,EchoData
EchoFillLoop:
stosw
add ax,EchoDataIncW
loop EchoFillLoop
EchoFillEnd:
mov si,offset EchoTarget-iIpSrc
call SwitchIpdstB ; set IP destination

mov si,offset EchoTarget
mov di,offset MsgEchoTarget
call PutIpNum ; tell who we are pinging

mov cx,EchoSize
or cx,cx
jns EchoSizePos
neg cx
mov MsgEchoSweep,'<'
EchoSizePos:
sub cx,IPHDRLEN+ICMPHDRLEN+4
cmp cx,GIANT-HWHDRLEN-IPHDRLEN-ICMPHDRLEN-4
jbe EchoOkSize
xor cx,cx
EchoOkSize:
mov ax,cx
add ax,IPHDRLEN+ICMPHDRLEN+4
mov EchoSize,cx
mov EchoMaxSize,cx

mov di,offset MsgEchoSize
mov PutMinDigits,1
call PutNum ; and the packet size used

mov ax,EchoInterval
mov di,offset MsgEchoMs
mov PutMinDigits,6
mov PutNumFiller,' '
call PutNum ; and interval in ms

mov dx,offset MsgEchoHead
mov ah,9
int 21h ; display it
EchoLoop0:
nop ; (just to separate the loops)
EchoLoop:
call Something2Do ; process other things
jnz EchoLoop ; maybe more to do

call EchoDisplay ; show current values

call AnyKey ; first key stops sending
jz EchoNoKey
if 0
cmp al,'y' and 01fh ; ignore most control keys
jbe EchoNoKey
endif
jmp EchoEnd
EchoNoKey:
cmp FreeBufs.lBufsAvail,3*NBUFS/4
jle EchoLoop ; prevent buffer starving

call HardwareTicks
call DblShrX
mov dx,ax
sub ax,EchoNext ; time to send next echo pkt?
js EchoLoop0

add dx,EchoInterval
mov EchoNext,dx ; next send time

add EchoTx32+2,1 ; increment send counters
adc EchoTx32,0
mov EchoFudge,1

mov cx,EchoSize ; compute packet size
cmp MsgEchoSweep,'<'
jne EchoFillFixed
inc cx
cmp cx,EchoMaxSize
jbe EchoFillSize
mov cx,28-IPHDRLEN-ICMPHDRLEN
EchoFillSize:
mov EchoSize,cx
EchoFillFixed:
add cx,ICMPHDRLEN+4 ; IP data length

mov di,cx
shl di,1
inc word ptr EchoSizeVec[di]

call HardwareTicks ; put timestamp
mov di,[bx].dPtrUdp
mov [di].uUdpData,ax
mov [di].uUdpData+2,dx

test GenFlags,UDP_ECHO
jnz EchoUdp
call SendIcmpPkt ; send icmp echo pkt
EchoLoop8:
jnz EchoErr ; any errors?
EchoLoop9:
mov EchoLastErr,cx
jmp EchoLoop

EchoUdp:
mov ax,cx
call SendUdpPkt ; send udp echo pkt
jmp short EchoLoop8

EchoErr:
cmp cx,EchoLastErr
je EchoLoop9

push cx
xor ch,ch
cmp cl,SERRTABLEN
jb EchoErrExist
mov cl,SERRTABLEN
EchoErrExist:
mov si,cx
mov dx,MsgSerrTbl[si]
mov ah,9
int 21h ; display send error
pop cx
test ArgFlags,TERM_WAIT
jnz EchoLoop9

EchoEnd:
call BufRelease ; release send buffer
mov EchoFudge,0
or ArgFlags,TERM_WAIT
ret
EchoAwhile endp



if DEBUG
TstBufLinks proc near
ja TstErrEI
mov si,di
inc cx
TstLinkLoop:
mov di,[di].dNext
mov si,[si].dPrev
loop TstLinkLoop
cmp si,di
jne TstErrEI
ret
TstBufLinks endp

TstErrEI:
PopfEI
TstErr:
push bx
mov bx,'>-'
push bx
push bx
call terminate
endif ; DEBUG



;************************************************************************
;* EchoDisplay
;************************************************************************


EchoDisplay proc near
if DEBUG
push bx
mov al,'s'-'0'
cmp word ptr phd_dioa,0 ; stack overflowed?
jne TstErr

mov al,'t'-'0'
cmp word ptr StackLow,0 ; stack overflowed?
jne TstErr

mov al,'i'-'0'
test GenFlags,DBGINTERR ; any interrupt debug errs?
jnz TstErr

mov cx,NBUFS ; any buffers damaged?
mov bx,offset BufStart
mov al,'u'-'0'
BufTestLoop:
cmp [bx].dHomeList,offset FreeBufs
jne TstErr
add bx,BUFSIZE
loop BufTestLoop

PushfDI
mov di,offset FreeBufs
mov cx,[di].lBufsAvail
cmp cx,NBUFS
call TstBufLinks
cmp di,offset FreeBufs
jne TstErrEI
PopfEI

mov cx,NBUFSMALL
mov al,'v'-'0'
TstSmlLoop:
cmp [bx].dHomeList,offset FreeSmal
jne TstErr
add bx,BUFSIZESML
loop TstSmlLoop

PushfDI
mov di,offset FreeSmal
mov cx,[di].lBufsAvail
cmp cx,NBUFSMALL
call TstBufLinks
cmp di,offset FreeSmal
jne TstErrEI
PopfEI
pop bx
endif ; DEBUG
; *test cmp EchoTarget,0 ; are we pinging?
; je EchoDispRet

call CurrentTicks
shr cx,1
shr cx,1
mov ax,EchoLastDispl
shr ax,1
shr ax,1
cmp ax,cx ; time to update display?
jne EchoDispNow
EchoDispRet:
ret

EchoDispNow:
push bx

cli
mov dx,EchoAvgSum
mov ax,EchoAvgSum+2
mov cx,EchoRx32
mov bx,EchoRx32+2
sti
call AdjTo16Bits
or bx,bx ; avoid div by zero
jz EchoSkipAvg

div bx
mov EchoAvg,ax ; average delay
EchoSkipAvg:

mov dx,EchoTx32 ; compute difference tx - rx
mov ax,EchoTx32+2
sub ax,EchoFudge ; subtract one if just
sbb dx,0 ; sent a pkt
push ax
push dx
cli
sub ax,EchoRx32+2
sbb dx,EchoRx32
sti
jns EchoDifPos ; use abs(tx-rx)
not ax
not dx
add ax,1
adc dx,0
EchoDifPos:
mov Echodif,dx
mov Echodif+2,ax

mov cl,2 ; compute packet loss
call DblShl ; multiply by 100
mov si,dx
mov bx,ax
mov cl,3
call DblShl
add bx,ax
adc si,dx
shl ax,1
rcl dx,1
add ax,bx
adc dx,si

pop cx
pop bx

call AdjTo16Bits
or bx,bx ; avoid div by zero
jz EchoSkipLoss

div bx
mov EchoLoss,ax

mov ax,dx ; fractional loss
mul k10000
div bx
mov EchoLoss+2,ax
EchoSkipLoss:
push cs ; edit echo values
pop es

mov di,offset MsgEcho-1
mov si,offset EchoTx32
mov PutNumFiller,' '
mov PutMinDigits,9
mov cx,3
call PutBigNums ; tx and rx and diff

mov PutMinDigits,6
inc di
mov cx,5
EchoDispLoop:
push cx
mov cl,1
call PutNums ; delays and loss
pop cx
loop EchoDispLoop

mov PutNumFiller,'0'
inc di
mov cl,1
call PutNumsD4 ; .0000%

cli
mov ax,EchoLoad+2
mov bx,ax
mov dx,EchoLoad
mov cx,dx
add ax,EchoPrevLoad+2
adc dx,EchoPrevLoad
mov EchoLoad+2,0
mov EchoLoad,0
sti
mov EchoPrevLoad+2,bx
mov EchoPrevLoad,cx
div k55 ; assumes clr every 2nd tick
add di,4
mov PutNumFiller,' '
call PutNum ; load kb/s

call HardwareTicks ; compute elapsed time
mov ax,dx
mov dx,si
cmp dx,EchoLastHi
jae EchoLastGrows

mov bx,EchoLastDispl
mov cx,EchoLastHi
sub EchoStart+2,bx
sbb EchoStart,cx
EchoLastGrows:
mov EchoLastDispl,ax
mov EchoLastHi,dx
sub ax,EchoStart+2
sbb dx,EchoStart
mov cl,4 ; divide # of ticks by 18.2
call DblShr
mov EchoElapsed+2,ax
mov EchoElapsed,dx
mov cl,3
call DblShr
sub EchoElapsed+2,ax
sbb EchoElapsed,dx
mov cl,5
call DblShr
add ax,EchoElapsed+2
adc dx,EchoElapsed
mov PutNumFiller,' '
mov PutMinDigits,8
call PutBigNum ; elapsed time
if DEBUG
mov dx,280h+10h ; assume WD card at IO 280h
xor ax,ax
xor cx,cx
cli
out dx,al ; set page 0
call IoDelay
add dx,0dh
in al,dx ; readandclear frame err ctr
add cx,ax
inc dx
in al,dx ; readnadclear bad CRC ctr
add cx,ax
inc dx
in al,dx ; readandclear lost frames ctr
sti
add cx,ax
add EchoDrop,cx ; add out of bufs ctr
endif ; DEBUG
mov ax,EchoDrop
if DEBUG eq 0
or ax,ax
jz EchoNoDrops
endif ; DEBUG eq 0
mov di,offset MsgEcho+18 ; place before diff
mov PutMinDigits,1
call PutNum ; show dropped packets
EchoNoDrops:
mov dx,offset MsgEcho ; display echo values
mov ah,9
int 21h

pop bx
ret
EchoDisplay endp



;************************************************************************
;* AdjTo16Bits
;************************************************************************

AdjTo16Bits proc near
AdjTest:
or cx,cx ; fits in 16 bits?
jnz Adjust
or dx,dx
jnz Adjust
ret
Adjust:
shr dx,1 ; shift 32 bits right
rcr ax,1
shr cx,1
rcr bx,1
jmp short AdjTest
AdjTo16Bits endp



;************************************************************************
;* DblShrX
;************************************************************************

DblShrX proc near
mov cx,7
test ArgFlags,MICRO_100
jnz DblShr
DblShr10:
mov cl,10
DblShr:
xor ch,ch
DblShrNext:
shr dx,1 ; shift 32 bits right
rcr ax,1
loop DblShrNext
ret
DblShrX endp



;************************************************************************
;* DblShl
;************************************************************************

DblShl proc near
xor ch,ch
DblShlNext:
shl ax,1 ; shift 32 bits left
rcl dx,1
loop DblShlNext
ret
DblShl endp



;************************************************************************
;* EchoCalc
;************************************************************************

even
kTimerScale dw TimerResolution

EchoCalc proc near

add EchoRx32+2,1 ; increment receive counters
adc EchoRx32,0
mov EchoFudge,0

mov di,[bx].dPktLen ; IP data length
shl di,1
dec word ptr EchoSizeVec[di]

call HardwareTicks ; compute delay
mov di,[bx].dPtrUdp
sub ax,[di].uUdpData
sbb dx,[di].uUdpData+2
js EchoCalcRet
div kTimerScale
mov EchoThis,ax ; delay for this packet

add EchoAvgSum+2,ax
adc EchoAvgSum,0

cmp ax,EchoMin
jb EchoSetMin
EchoChkMax:
cmp ax,EchoMax
ja EchoSetMax
EchoCalcRet:
ret

EchoSetMin:
mov EchoMin,ax ; minimum delay
jmp short EchoChkMax
EchoSetMax:
mov EchoMax,ax ; maximum delay
ret
EchoCalc endp



;************************************************************************
;* HardwareTicks (48 bit time to si:dx:ax in 838 ns units)
;************************************************************************

TimerResolution equ 1193 ; hw ticks per millisecond

InitTimer proc near
test ArgFlags,TIM_NOHIRES
jnz InitTimRet
mov dx,043h ; select timer control port
mov al,034h
out dx,al ; mode 2: Rate generator
call IoDelay ; (counts down by 1 to zero)
xor ax,ax
mov dx,040h ; select timer 0
out dx,al ; set divide by 2**16
call IoDelay
out dx,al ; the generator is now started
InitTimRet:
ret
InitTimer endp

RestoreTimer proc near
test ArgFlags,TIM_NOHIRES
jnz ResTimRet
mov dx,043h ; select timer control port
mov al,036h
out dx,al ; mode 3: Square wave generator
call IoDelay ; (counts down by 2 to zero,
xor ax,ax ; twice)
mov dx,040h ; select timer 0
out dx,al ; set divide by 2**16
call IoDelay
out dx,al
ResTimRet:
ret
RestoreTimer endp

IoDelay proc near
push ax
in al,061h
pop ax
ret
IoDelay endp

HardwareTicks proc near
push es
PushfDI
test ArgFlags,TIM_NOHIRES
jnz HwTicksNoHi

mov dx,020h ;/* Address PIC ocw3 */
mov al,00Ah ;/* Ask to read irr */
out dx,al

xor al,al ;/* Latch timer 0 */
out 043h,al
in al,040h ;/* Counter --> ax*/
mov ah,al ;/* LSB in AH */
in al,040h ;/* MSB in AL */
xchg al,ah
not ax ;/* Need ascending counter */
push ax ; Save hardware counter value

in al,dx ;/* Read irr */
push ax ; Save irr

in al,021h ;/* Read PIC imr */
push ax ; Save imr

mov al,00FFh ;/* Mask all interrupts */
out 021h,al

mov ax,040h ;/* read low word of time */
mov es,ax ;/* from BIOS data area */
mov dx,es:[06Ch]
mov si,es:[06Ch+2] ; get high word too

pop ax ; Restore imr
out 021h,al
pop ax ; Restore irr
test al,001h ;/* Counter hit 0? */
pop ax ; Restore counter value
jnz HwTicksMore ;/* Jump if yes */
popfEI
pop es
ret

HwTicksMore:
cmp ax,0FFh ;/* Counter > 0x0FF? */
ja HwTicksDone ;/* Done if so */

inc dx ;/* Else count int req. */
HwTicksDone:
popfEI
pop es
ret

HwTicksNoHi:
mov ax,040h ;/* read low word of time */
mov es,ax ;/* from BIOS data area */
mov dx,es:[06Ch]
mov si,es:[06Ch+2]
xor ax,ax
popfEI
pop es
ret
HardwareTicks endp



;========================================================================
; endinclude


  3 Responses to “Category : Network Files
Archive   : PDCLK145.ZIP
Filename : PING.ASM

  1. Very nice! Thank you for this wonderful archive. I wonder why I found it only now. Long live the BBS file archives!

  2. This is so awesome! 😀 I’d be cool if you could download an entire archive of this at once, though.

  3. But one thing that puzzles me is the “mtswslnkmcjklsdlsbdmMICROSOFT” string. There is an article about it here. It is definitely worth a read: http://www.os2museum.com/wp/mtswslnk/