home *** CD-ROM | disk | FTP | other *** search
- ; ping.asm
- ;========================================================================
-
- ; Copyright (C) 1991 by Jan.Engvald@ldc.lu.se, 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
- 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 30
- 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
- EchoDrop dw 0
- PingRowCnt dw 17
-
- 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
-
- k27 dw 27
- k55 dw 55
- k100 dw 100
-
-
- ;************************************************************************
- ;* EchoAwhile
- ;************************************************************************
-
- MsgCalling db "Calling nameserver(s)... $"
- MsgNameRep db "got reply in "
- MsgNameRepTim db " ms.", CR, LF, '$'
- MsgBadName db LF, "Bad hostname.$"
-
- 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 DblShr10
- 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
- EchoRet:
- ret
-
- 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 EchoRet
-
- call MakeSendDescr
- ;*test mov [bx].dTickTimeout,8*18
- mov [di].uIcmpTypeCode,8 ; type = echo request
- mov cx,(1500-IPHDRLEN-ICMPHDRLEN)/2
- add di,ICMPHDRLEN
- 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
- cmp cx,GIANT-HWHDRLEN-IPHDRLEN-ICMPHDRLEN
- jbe EchoOkSize
- mov cx,30-IPHDRLEN-ICMPHDRLEN
- EchoOkSize:
- mov ax,cx
- add ax,IPHDRLEN+ICMPHDRLEN
- 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 DblShr10
- 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 ; IP data length
-
- mov ax,cx
- add ax,IPHDRLEN+14+8+4+12 ; preamble, crc, intergap ...
- cli
- add EchoLoad+2,ax
- adc EchoLoad,0
- sti
-
- mov di,cx
- shl di,1
- inc word ptr EchoSizeVec[di]
-
- call HardwareTicks ; put timestamp
- mov di,[bx].dPtrUdp
- mov [di].uIcmpData,ax
- mov [di].uIcmpData+2,dx
-
- call SendIcmpPkt ; send echo pkt
- jnz EchoErr ; any errors?
- jmp EchoLoop
-
- EchoErr:
- 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
- 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
- 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 dx,EchoLoad
- mov EchoLoad+2,0
- mov EchoLoad,0
- sti
- div k27 ; 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
- mov di,offset MsgEcho+18 ; place before diff
- mov ax,EchoDrop
- mov PutMinDigits,1
- call PutNum ; show dropped packets
- endif ; DEBUG
-
- 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
-
-
-
- ;************************************************************************
- ;* DblShr
- ;************************************************************************
-
- DblShr10 proc near
- mov cl,10
- DblShr:
- xor ch,ch
- DblShrNext:
- shr dx,1 ; shift 32 bits right
- rcr ax,1
- loop DblShrNext
- ret
- DblShr10 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 ax,[bx].dPktLen ; IP data length
- mov di,ax
- add ax,IPHDRLEN+14+8+4+12 ; preamble, crc, intergap
- add EchoLoad+2,ax
- adc EchoLoad,0
-
- shl di,1
- dec word ptr EchoSizeVec[di]
-
- call HardwareTicks ; compute delay
- mov di,[bx].dPtrUdp
- sub ax,[di].uIcmpData
- sbb dx,[di].uIcmpData+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
- ;*test 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
-