kolibrios-fun/programs/network/netstat/netstat.asm
hidnplayr f87f6d92df Netstat: fix speed indicators
git-svn-id: svn://kolibrios.org@7513 a494cfbc-eb01-0410-851d-a64ba20cac60
2018-10-30 22:05:26 +00:00

978 lines
22 KiB
NASM

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2010-2018. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;; netstat.asm - Network Status Tool for KolibriOS ;;
;; ;;
;; Written by hidnplayr@kolibrios.org ;;
;; ;;
;; GNU GENERAL PUBLIC LICENSE ;;
;; Version 2, June 1991 ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
format binary as ""
BOX_WIDTH = 390
BOX_HEIGHT = 185
use32
org 0x0
db 'MENUET01' ; 8 byte id
dd 0x01 ; header version
dd START ; start of code
dd I_END ; size of image
dd (I_END+0x1000) ; memory for app
dd (I_END+0x1000) ; esp
dd 0, 0 ; I_Param, I_Path
include '../../proc32.inc'
include '../../macros.inc'
include '../../dll.inc'
include '../../develop/libraries/box_lib/trunk/box_lib.mac'
include '../../network.inc'
include 'ipcfg.inc'
START:
mcall 68, 11
stdcall dll.Load, @IMPORT
or eax, eax
jnz exit
mcall 40, EVM_REDRAW + EVM_BUTTON + EVM_STACK2 + EVM_KEY
window_redraw:
; get system colors
mcall 48, 3, sc, 40
; Notify kernel of start of window draw
mcall 12, 1
; Draw the window
mcall 0, 100 shl 16 + 600, 100 shl 16 + 240, 0x34E1E1E1, , name
; Define the buttons (for tabs)
mov ebx, 5 shl 16 + 54
mov ecx, 4 shl 16 + 21
mov edx, 0x60000000 + 101
.buttonloop:
mcall 8
add ebx, 60 shl 16
inc edx
cmp dl, 106
jle .buttonloop
; draw sides and upper lines of the tab buttons
mov eax, 13
mov ebx, 5 shl 16 + 1
mov ecx, 4 shl 16 + 21
mov edx, 0x00777777
.loop:
mcall
mov bx, 54
mov cx, 1
mcall
mov bx, 1
mov cx, 21
add ebx, 54 shl 16
mcall
add ebx, 6 shl 16
cmp ebx, 360 shl 16
jb .loop
; Draw sides and bottom lines of the rectangle
mcall , 0 shl 16 + 1, 25 shl 16 + BOX_HEIGHT;, 0x00777777
mcall , (0+BOX_WIDTH) shl 16 +1, 25 shl 16 + (BOX_HEIGHT+1)
mcall , 0 shl 16 + BOX_WIDTH, (25+BOX_HEIGHT) shl 16 + 1
redraw:
; Draw interface buttons (on the right hand side)
call draw_interfaces
; Draw upper line of rectangle
mcall 13, 0 shl 16 + BOX_WIDTH, 25 shl 16 + 1, 0x00777777
; Fill rectangle
mcall 13, 1 shl 16 + BOX_WIDTH-1, 26 shl 16 + BOX_HEIGHT-1, 0x00F3F3F3
; Undefine IP settings button
mov edx, 0x80000002
mcall 8
; Fill tab buttons
mov eax, 13
mov ebx, 6 shl 16 + 53
mov si, 101
.buttonloop:
mov ecx, 6 shl 16 + 19
mov edx, 0x00BBBBBB
cmp si, [mode]
jne @f
mov edx, 0x00F3F3F3 ; Activated button has other colors
inc ecx
@@:
mcall
mov edx, 0x00E1E1E1
cmp si, [mode]
jne @f
mov edx, 0x00FFFFFF ; Activated button has other colors
@@:
mov ecx, 5 shl 16 + 1
mcall
add ebx, 60 shl 16
inc si
cmp si, 106
jle .buttonloop
; Print button names on top of the buttons
mcall 4, 9 shl 16 + 12, 0x80000000, modes
; Get information about the selected device
xor ebx, ebx
mov bh, [device]
mcall 74
mov [device_type], eax
cmp [mode], 101
jne .no_eth
mcall 4, 8 shl 16 + 35, 0x80000000, str_packets_tx
add ebx, 18
mov edx, str_packets_rx
mcall
add ebx, 18
mov edx, str_bytes_tx
mcall
add ebx, 18
mov edx, str_bytes_rx
mcall
add ebx, 18
mov edx, str_speed_tx
mcall
add ebx, 18
mov edx, str_speed_rx
mcall
add ebx, 18
mov edx, str_link
mcall
cmp [device_type], 1
jne end_of_draw
add ebx, 18
mov edx, str_MAC
mcall
mov ebx, API_ETH
mov bh, [device]
mcall 76
push eax
push bx
mov edx, 134 shl 16 + 35 + 7*18
call draw_mac
jmp end_of_draw
.no_eth:
cmp [mode], 102
jne .no_ip
mcall 4, 8 shl 16 + 35, 0x80000000, str_packets_tx
add ebx, 18
mov edx, str_packets_rx
mcall
add ebx, 18
mov edx, str_ip
mcall
add ebx, 18
mov edx, str_dns
mcall
add ebx, 18
mov edx, str_subnet
mcall
add ebx, 18
mov edx, str_gateway
mcall
mov ebx, API_IPv4 + 8
mov bh, [device]
mcall 76
push eax
dec bl
dec bl
mcall 76
push eax
dec bl
dec bl
mcall 76
push eax
dec bl
dec bl
mcall 76
push eax
mov edx, 134 shl 16 + 35 + 2*18
call draw_ip
add edx, 18
call draw_ip
add edx, 18
call draw_ip
add edx, 18
call draw_ip
cmp [device], 0
je end_of_draw
mcall 8, 128 shl 16 + 100, 150 shl 16 + 20, 2, [sc.work_button]
mcall 4, 150 shl 16 + 157, [sc.work_button_text], str_ip_cfg, str_ip_cfg.len
jmp end_of_draw
.no_ip:
cmp [mode], 103
jne .no_arp
mcall 4, 8 shl 16 + 35, 0x80000000, str_packets_tx
add ebx, 18
mov edx, str_packets_rx
mcall
add ebx, 18
mov edx, str_arp
mcall
add ebx, 18
mov edx, str_conflicts
mcall
mcall 4, 8 shl 16 + 130, 0x80000000, str_ARP_legend
jmp end_of_draw
.no_arp:
mcall 4, 8 shl 16 + 35, 0x80000000, str_packets_tx
add ebx, 18
mov edx, str_packets_rx
mcall
cmp [mode], 106
jne end_of_draw
add ebx, 18
mov edx, str_missed
mcall
add ebx, 18
mov edx, str_dumped
mcall
add ebx, 18
mov edx, str_queued
mcall
end_of_draw:
mcall 12, 2
draw_stats:
cmp [mode], 101
jne not_101
mov ebx, API_ETH
mov bh, [device]
mov bl, 6
@@:
push ebx
mcall 74
pop ebx
push eax
inc bl
cmp bl, 10
jbe @r
pop ecx
push [time]
pop [delta_time]
mcall 26, 9 ; TODO: use 26, 10 instead
mov [time], eax
sub eax, [delta_time]
jnz @f
inc eax ; Zero time units? Lets make it at least one.
@@:
lea eax, [eax + 4*eax]
shl eax, 1
mov [delta_time], eax
mov eax, [esp+4] ; bytes received
push eax
sub eax, [prev_rx]
pop [prev_rx]
xor edx, edx
div [delta_time]
push eax
mov eax, [esp+4] ; bytes sent
push eax
sub eax, [prev_tx]
pop [prev_tx]
xor edx, edx
div [delta_time]
push eax
test cl, cl
jnz @f
mov edx, str_down
jmp .print_link
@@:
cmp cl, 100b
jnz @f
mov edx, str_10m
jmp .print_link
@@:
cmp cl, 110b
jnz @f
mov edx, str_10mfd
jmp .print_link
@@:
cmp cl, 1000b
jnz @f
mov edx, str_100m
jmp .print_link
@@:
cmp cl, 1010b
jnz @f
mov edx, str_100mfd
jmp .print_link
@@:
cmp cl, 1100b
jnz @f
mov edx, str_1g
jmp .print_link
@@:
cmp cl, 1110b
jnz @f
mov edx, str_1gfd
jmp .print_link
@@:
mov edx, str_unknown
.print_link:
mov ebx, 134 shl 16 + 35 + 6*18
mov ecx, 0xc0000000
mov edi, 0x00f3f3f3
mcall 4
; speed tx
mov ebx, 0x000a0000
pop ecx
mov edx, 134 shl 16 + 35 + 5*18
mov esi, 0x40000000
mcall 47
; speed rx
sub edx, 18
pop ecx
mcall
; bytes received
sub edx, 18
pop ecx
mcall
; bytes sent
sub edx, 18
pop ecx
mcall
; packets received
sub edx, 18
pop ecx
mcall
; packets sent
sub edx, 18
pop ecx
mcall
jmp mainloop
not_101:
cmp [mode], 102
jne not_102
mov ebx, API_IPv4
mov bh, [device]
push ebx
mcall 76
pop ebx
push eax
inc bl
push ebx
mcall 76
pop ebx
push eax
mov ebx, 0x000a0000
pop ecx
mov edx, 134 shl 16 + 35 + 18
mov esi, 0x40000000
mov edi, 0x00F3F3F3
mcall 47
sub edx, 18
pop ecx
mcall
jmp mainloop
not_102:
cmp [mode], 103
jne not_103
mov ebx, API_ARP
mov bh, [device]
push ebx
mcall 76 ; tx
pop ebx
push eax
inc bl
push ebx
mcall 76 ; rx
pop ebx
push eax
inc bl
push ebx
mcall 76 ; entries
pop ebx
push eax
mov bl, 7
push ebx
mcall 76
pop ebx
push eax
mov ebx, 0x000a0000
pop ecx
mov edx, 134 shl 16 + 35 + 3*18
mov esi, 0x40000000
mov edi, 0x00F3F3F3
mcall 47
sub edx, 18
pop ecx
mcall
sub edx, 18
pop ecx
mcall
sub edx, 18
pop ecx
mcall
; mov edx, 50 shl 16 + 150
mov [last], 0
.arp_loop:
mov ebx, API_ARP + 3 ; read ARP entry
mov bh, [device]
mcall 76, ,[last], , , arp_buf
cmp eax, -1
je mainloop
mov ebx, [last]
imul ebx, 16
add ebx, 8 shl 16 + 140
mcall 4, , 0x80000000, str_ARP_entry
mov edx, ebx
mov eax, 47
mov ebx, 0x00030000
mov esi, 0x40000000
mov edi, 0x00F3F3F3
xor ecx, ecx
mov cl, byte[arp_buf.IP+0]
mcall
mov cl, byte[arp_buf.IP+1]
add edx, 24 shl 16
mcall
mov cl, byte[arp_buf.IP+2]
add edx, 24 shl 16
mcall
mov cl, byte[arp_buf.IP+3]
add edx, 24 shl 16
mcall
mov ebx, 0x00020100
mov cl, byte[arp_buf.MAC+0]
add edx, 36 shl 16
mcall
mov cl, byte[arp_buf.MAC+1]
add edx, 18 shl 16
mcall
mov cl, byte[arp_buf.MAC+2]
add edx, 18 shl 16
mcall
mov cl, byte[arp_buf.MAC+3]
add edx, 18 shl 16
mcall
mov cl, byte[arp_buf.MAC+4]
add edx, 18 shl 16
mcall
mov cl, byte[arp_buf.MAC+5]
add edx, 18 shl 16
mcall
mov ebx, 0x00040000
mov cx, [arp_buf.status]
add edx, 30 shl 16
mcall
mov cx, [arp_buf.TTL]
add edx, 60 shl 16
mcall
add dx, 18
rol edx, 16
mov dx, 8
rol edx, 16
inc [last]
jmp .arp_loop
not_103:
cmp [mode], 104
jne not_104
mov ebx, API_ICMP
mov bh, [device]
push ebx
mcall 76
pop ebx
push eax
inc bl
push ebx
mcall 76
pop ebx
push eax
mov ebx, 0x000a0000
pop ecx
mov edx, 134 shl 16 + 35 + 18
mov esi, 0x40000000
mov edi, 0x00F3F3F3
mcall 47
sub edx, 18
pop ecx
mcall
jmp mainloop
not_104:
cmp [mode], 105
jne not_105
mov ebx, API_UDP
mov bh, [device]
push ebx
mcall 76
pop ebx
push eax
inc bl
push ebx
mcall 76
pop ebx
push eax
mov ebx, 0x000a0000
pop ecx
mov edx, 134 shl 16 + 35 + 18
mov esi, 0x40000000
mov edi, 0x00F3F3F3
mcall 47
sub edx, 18
pop ecx
mcall
jmp mainloop
not_105:
cmp [mode], 106
jne not_106
mov ebx, API_TCP
mov bh, [device]
push ebx
mcall 76
pop ebx
push eax
inc bl
push ebx
mcall 76
pop ebx
push eax
inc bl
push ebx
mcall 76
pop ebx
push eax
inc bl
push ebx
mcall 76
pop ebx
push eax
inc bl
push ebx
mcall 76
pop ebx
push eax
mov ebx, 0x000a0000
pop ecx
mov edx, 134 shl 16 + 35 + 18*4
mov esi, 0x40000000
mov edi, 0x00F3F3F3
mcall 47
sub edx, 18
pop ecx
mcall
sub edx, 18
pop ecx
mcall
sub edx, 18
pop ecx
mcall
sub edx, 18
pop ecx
mcall
jmp mainloop
not_106:
mainloop:
mcall 23, 50 ; wait for event with timeout (0,5 s)
cmp eax, EV_REDRAW
je window_redraw
cmp eax, EV_BUTTON
je button
cmp eax, EV_KEY
je key
cmp eax, 11
je redraw
jmp draw_stats
button: ; button
mcall 17 ; get id
cmp ah, 1
je exit
cmp ah, 2
je .ipcfg
cmp ah, 0
je .interface
shr ax, 8
mov [mode], ax
jmp redraw
.ipcfg:
mcall 51, 1, ipcfg, I_END+0x1000
jmp mainloop
.interface:
shr eax, 16
mov [device], al
jmp redraw
key:
mcall 2
cmp ah, 9
je .tab
cmp ah, 183
je .pgdown
cmp ah, 184
je .pgup
jmp mainloop
.tab:
inc [mode]
cmp [mode], 106
jbe redraw
mov [mode], 101
jmp redraw
.pgdown:
inc [device]
mov al, [device]
cmp al, [last_device]
jbe redraw
mov [device], 0
jmp redraw
.pgup:
dec [device]
cmp [device], 0
jge redraw
mov al, [last_device]
mov [device], al
jmp redraw
exit:
mcall -1
draw_mac:
mov eax, 47
mov ebx, 0x00020100
mov esi, 0x40000000
mov edi, 0x00F3F3F3
mov cl, [esp+4]
mcall
mov cl, [esp+4+1]
add edx, 18 shl 16
mcall
mov cl, [esp+4+2]
add edx, 18 shl 16
mcall
mov cl, [esp+4+3]
add edx, 18 shl 16
mcall
mov cl, [esp+4+4]
add edx, 18 shl 16
mcall
mov cl, [esp+4+5]
add edx, 18 shl 16
mcall
sub edx, 5*18 shl 16
ret 6
draw_ip:
mov eax, 47
mov ebx, 0x00030000
mov esi, 0x40000000
mov edi, 0x00F3F3F3
xor ecx, ecx
mov cl, [esp+4]
mcall
mov cl, [esp+4+1]
add edx, 24 shl 16
mcall
mov cl, [esp+4+2]
add edx, 24 shl 16
mcall
mov cl, [esp+4+3]
add edx, 24 shl 16
mcall
sub edx, 3*24 shl 16
ret 4
draw_interfaces:
mov [.btnpos], 5 shl 16 + 20
mov [.txtpos], 405 shl 16 + 12
mcall 74, -1 ; get number of active network devices
mov ecx, eax
dec al
mov [last_device], al
cmp [device], al
jbe @f
mov [device], 0
@@:
xor ebx, ebx ; get device type
.loop:
mcall 74
cmp eax, 1 ; loopback or ethernet?
jbe .hit
inc bh
jb .loop ; tried all 256?
ret
.hit:
push ecx ebx
movzx edx, bh
shl edx, 8
mov esi, 0x00BBBbbb
cmp bh, [device]
cmove esi, 0x0081BBFF
mcall 8, 400 shl 16 + 185, [.btnpos]
mov ebx, [esp]
inc bl
mov ecx, namebuf
mov edx, namebuf
mcall 74 ; get device name
cmp eax, -1
jne @f
mov edx, str_unknown
@@:
mcall 4, [.txtpos], 0x80000000 ; print the name
pop ebx ecx
inc bh
add [.btnpos], 25 shl 16
add [.txtpos], 25
dec ecx
jnz .loop
ret
.btnpos dd ?
.txtpos dd ?
; DATA AREA
align 16
@IMPORT:
library box_lib , 'box_lib.obj', \
libini , 'libini.obj'
import libini, \
ini.get_str , 'ini_get_str' ,\
ini.set_str , 'ini_set_str' ,\
ini.enum_sections, 'ini_enum_sections'
import box_lib ,\
edit_box_draw , 'edit_box' ,\
edit_box_key , 'edit_box_key' ,\
edit_box_mouse , 'edit_box_mouse' ,\
edit_set_text , 'edit_box_set_text' ,\
version_ed , 'version_ed' ,\
init_checkbox , 'init_checkbox2' ,\
check_box_draw , 'check_box_draw2' ,\
check_box_mouse , 'check_box_mouse2' ,\
version_ch , 'version_ch2' ,\
option_box_draw , 'option_box_draw' ,\
option_box_mouse, 'option_box_mouse' ,\
version_op , 'version_op'
name db 'Network status', 0
mode dw 101 ; currently selected protocol
device db 1 ; currently selected device
last_device db ? ; last device available
device_type dd ?
last dd ?
modes db 'Physical IPv4 ARP ICMP UDP TCP', 0
str_packets_tx db 'Packets sent:', 0
str_packets_rx db 'Packets received:', 0
str_bytes_tx db 'Bytes sent:', 0
str_bytes_rx db 'Bytes received:', 0
str_MAC db 'MAC address: - - - - -', 0
str_ip db 'IP address: . . .', 0
str_dns db 'DNS address: . . .', 0
str_subnet db 'Subnet mask: . . .', 0
str_gateway db 'Standard gateway: . . .', 0
str_arp db 'ARP entrys:', 0
str_conflicts db 'ARP conflicts:', 0
str_missed db 'Packets missed:', 0
str_dumped db 'Packets dumped:', 0
str_queued db 'Packets queued:', 0
str_link db 'Link state:', 0
str_speed_tx db 'Upload (kb/s):', 0
str_speed_rx db 'Download (kb/s):', 0
str_ip_cfg db 'Configure'
.len = $ - str_ip_cfg
str_down db 'disconnected ', 0
str_unknown db 'unknown ', 0
str_10m db '10 Mbit Half duplex ', 0
str_10mfd db '10 Mbit Full duplex ', 0
str_100m db '100 Mbit Half duplex', 0
str_100mfd db '100 Mbit Full duplex', 0
str_1g db '1 Gbit Half duplex ', 0
str_1gfd db '1 Gbit Full duplex ', 0
str_ARP_legend db 'IP-address MAC-address Status TTL', 0
str_ARP_entry db ' . . . - - - - -', 0
prev_rx dd ?
prev_tx dd ?
time dd ?
delta_time dd ?
namebuf rb 64
arp_buf ARP_entry
sc system_colors
I_END: