fix in ARPcfg application

added pci ids of dec21x4x cards to netcfg
bugfixes in dex21x4x driver, pcnet32 driver, rtl8139 driver and sis900 driver
new network program (ICMP) to ping computers, uses new RAW socket code (experimental)

git-svn-id: svn://kolibrios.org@1541 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
hidnplayr 2010-07-30 21:54:27 +00:00
parent 500fea459a
commit 8a7ebf6b32
12 changed files with 745 additions and 435 deletions

View File

@ -147,8 +147,6 @@ START: ; start of execution
; DATA AREA ; DATA AREA
IM_END:
name db 'ARP manager',0 name db 'ARP manager',0
title db '# IP-address MAC-address Status TTL',0 title db '# IP-address MAC-address Status TTL',0
@ -166,6 +164,8 @@ ARP_ENTRY:
include_debug_strings ; ALWAYS present in data section include_debug_strings ; ALWAYS present in data section
IM_END:
I_PARAM rb 1024 I_PARAM rb 1024
I_END: I_END:

View File

@ -0,0 +1,319 @@
use32
org 0x0
; standard header
db 'MENUET01' ; signature
dd 1 ; header version
dd start ; entry point
dd I_END ; initialized size
dd mem ; required memory
dd mem ; stack pointer
dd 0 ; parameters
dd 0 ; path
BUFFERSIZE equ 1500
; useful includes
include '../macros.inc'
purge mov,add,sub
include '../proc32.inc'
include '../dll.inc'
include '../network.inc'
; ICMP types & codes
ICMP_ECHOREPLY equ 0 ; echo reply message
ICMP_UNREACH equ 3
ICMP_UNREACH_NET equ 0 ; bad net
ICMP_UNREACH_HOST equ 1 ; bad host
ICMP_UNREACH_PROTOCOL equ 2 ; bad protocol
ICMP_UNREACH_PORT equ 3 ; bad port
ICMP_UNREACH_NEEDFRAG equ 4 ; IP_DF caused drop
ICMP_UNREACH_SRCFAIL equ 5 ; src route failed
ICMP_UNREACH_NET_UNKNOWN equ 6 ; unknown net
ICMP_UNREACH_HOST_UNKNOWN equ 7 ; unknown host
ICMP_UNREACH_ISOLATED equ 8 ; src host isolated
ICMP_UNREACH_NET_PROHIB equ 9 ; prohibited access
ICMP_UNREACH_HOST_PROHIB equ 10 ; ditto
ICMP_UNREACH_TOSNET equ 11 ; bad tos for net
ICMP_UNREACH_TOSHOST equ 12 ; bad tos for host
ICMP_UNREACH_FILTER_PROHIB equ 13 ; admin prohib
ICMP_UNREACH_HOST_PRECEDENCE equ 14 ; host prec vio.
ICMP_UNREACH_PRECEDENCE_CUTOFF equ 15 ; prec cutoff
ICMP_SOURCEQUENCH equ 4 ; Packet lost, slow down
ICMP_REDIRECT equ 5 ; shorter route, codes:
ICMP_REDIRECT_NET equ 0 ; for network
ICMP_REDIRECT_HOST equ 1 ; for host
ICMP_REDIRECT_TOSNET equ 2 ; for tos and net
ICMP_REDIRECT_TOSHOST equ 3 ; for tos and host
ICMP_ALTHOSTADDR equ 6 ; alternate host address
ICMP_ECHO equ 8 ; echo service
ICMP_ROUTERADVERT equ 9 ; router advertisement
ICMP_ROUTERADVERT_NORMAL equ 0 ; normal advertisement
ICMP_ROUTERADVERT_NOROUTE_COMMON equ 16 ; selective routing
ICMP_ROUTERSOLICIT equ 10 ; router solicitation
ICMP_TIMXCEED equ 11 ; time exceeded, code:
ICMP_TIMXCEED_INTRANS equ 0 ; ttl==0 in transit
ICMP_TIMXCEED_REASS equ 1 ; ttl==0 in reass
ICMP_PARAMPROB equ 12 ; ip header bad
ICMP_PARAMPROB_ERRATPTR equ 0 ; error at param ptr
ICMP_PARAMPROB_OPTABSENT equ 1 ; req. opt. absent
ICMP_PARAMPROB_LENGTH equ 2 ; bad length
ICMP_TSTAMP equ 13 ; timestamp request
ICMP_TSTAMPREPLY equ 14 ; timestamp reply
ICMP_IREQ equ 15 ; information request
ICMP_IREQREPLY equ 16 ; information reply
ICMP_MASKREQ equ 17 ; address mask request
ICMP_MASKREPLY equ 18 ; address mask reply
ICMP_TRACEROUTE equ 30 ; traceroute
ICMP_DATACONVERR equ 31 ; data conversion error
ICMP_MOBILE_REDIRECT equ 32 ; mobile host redirect
ICMP_IPV6_WHEREAREYOU equ 33 ; IPv6 where-are-you
ICMP_IPV6_IAMHERE equ 34 ; IPv6 i-am-here
ICMP_MOBILE_REGREQUEST equ 35 ; mobile registration req
ICMP_MOBILE_REGREPLY equ 36 ; mobile registreation reply
ICMP_SKIP equ 39 ; SKIP
ICMP_PHOTURIS equ 40 ; Photuris
ICMP_PHOTURIS_UNKNOWN_INDEX equ 1 ; unknown sec index
ICMP_PHOTURIS_AUTH_FAILED equ 2 ; auth failed
ICMP_PHOTURIS_DECRYPT_FAILED equ 3 ; decrypt failed
virtual at 0
ICMP_Packet:
.Type db ?
.Code db ?
.Checksum dw ?
.Identifier dw ?
.SequenceNumber dw ?
.Data:
end virtual
; entry point
start:
; load libraries
stdcall dll.Load, @IMPORT
test eax, eax
jnz exit
; initialize console
push 1
call [con_start]
push title
push 25
push 80
push 25
push 80
call [con_init]
; main loop
push str1
call [con_write_asciiz]
main:
; write prompt
push str2
call [con_write_asciiz]
; read string
mov esi, s
push 256
push esi
call [con_gets]
; check for exit
test eax, eax
jz done
cmp byte [esi], 10
jz done
; delete terminating '\n'
push esi
@@:
lodsb
test al, al
jnz @b
mov byte [esi-2], al
pop esi
; resolve name
push esp ; reserve stack place
push esp ; fourth parameter
push 0 ; third parameter
push 0 ; second parameter
push esi ; first parameter
call [getaddrinfo]
pop esi
; test for error
test eax, eax
jnz fail
; convert IP address to decimal notation
mov eax, [esi+addrinfo.ai_addr]
mov eax, [eax+sockaddr_in.sin_addr]
mov [sockaddr1.ip], eax
push eax
call [inet_ntoa]
; write result
mov [ip_ptr], eax
push eax
; free allocated memory
push esi
call [freeaddrinfo]
push str4
call [con_write_asciiz]
mcall socket, AF_INET4, SOCK_RAW, IPPROTO_ICMP
cmp eax, -1
jz fail2
mov [socketnum], eax
mcall connect, [socketnum], sockaddr1, 18
mcall 40, 1 shl 7 ; + 7
; call [con_cls]
mov [count], 4
mainloop:
push str3
call [con_write_asciiz]
push [ip_ptr]
call [con_write_asciiz]
mcall 26,9
mov [time_reference], eax
mcall send, [socketnum], icmp_packet, icmp_packet.length, 0
mcall 23, 300 ; 3 seconds time-out
mcall 26,9
neg [time_reference]
add [time_reference], eax
mcall recv, [socketnum], buffer_ptr, BUFFERSIZE, 0
cmp eax, -1
je .no_response
; validate the packet
lea esi, [buffer_ptr + ICMP_Packet.Data]
mov edi, icmp_packet.data
mov ecx, 32/4
repe cmpsd
jne .miscomp
push [time_reference]
push str7
call [con_printf]
jmp continue
.miscomp:
sub edi, icmp_packet.data
push edi
push str9
call [con_printf]
jmp continue
.no_response:
push str8
call [con_write_asciiz]
continue:
dec [count]
jz done
mcall 5, 100 ; wait a second
inc [icmp_packet.id]
jmp mainloop
done:
push str10
call [con_write_asciiz]
call [con_getch2]
push 1
call [con_exit]
exit:
mcall -1
fail:
push str5
call [con_write_asciiz]
jmp done
fail2:
push str6
call [con_write_asciiz]
jmp done
; data
title db 'ICMP - test application',0
str1 db 'ICMP test application v0.1',10,' for KolibriOS # 1540 or later. ',10,10,0
str2 db '> ',0
str3 db 'Ping to: ',0
str4 db 10,0
str5 db 'Name resolution failed.',10,10,0
str6 db 'Could not open socket',10,10,0
str7 db ' time= %u0ms',10,0
str8 db ' timeout!',10,0
str9 db ' miscompare at offset %u',10,0
str10 db 10,10,'Press any key to exit',0
sockaddr1:
dw AF_INET4
.port dw 0
.ip dd 0
rb 10
time_reference dd ?
ip_ptr dd ?
count dd ?
; import
align 4
@IMPORT:
library network, 'network.obj', console, 'console.obj'
import network, \
getaddrinfo, 'getaddrinfo', \
freeaddrinfo, 'freeaddrinfo', \
inet_ntoa, 'inet_ntoa'
import console, \
con_start, 'START', \
con_init, 'con_init', \
con_write_asciiz, 'con_write_asciiz', \
con_printf, 'con_printf', \
con_exit, 'con_exit', \
con_gets, 'con_gets',\
con_cls, 'con_cls',\
con_getch2, 'con_getch2',\
con_set_cursor_pos, 'con_set_cursor_pos'
socketnum dd ?
icmp_packet: db 8 ; type
db 0 ; code
dw 0 ;
.id dw 0x0000 ; identifier
.seq dw 0x0001 ; sequence number
.data db 'abcdefghijklmnopqrstuvwxyz012345678'
.length = $ - icmp_packet
I_END:
buffer_ptr rb BUFFERSIZE
s rb 256
align 4
rb 4096 ; stack
mem:

View File

@ -135,4 +135,9 @@ dd 0x08001516
dd 0x08911516 dd 0x08911516
dd 0x0 dd 0x0
db 'dec21x4x',0
dd 0x000901011
dd 0x001901011
dd 0x0
dd 0x0 ; driverlist end dd 0x0 ; driverlist end

View File

@ -1,157 +0,0 @@
;-----------------------------------------------------------------------------
proc mem.Alloc size ;/////////////////////////////////////////////////////////
;-----------------------------------------------------------------------------
push ebx ecx
mov eax,[size]
lea ecx,[eax+4+4095]
and ecx,not 4095
mcall 68,12
add ecx,-4
mov [eax],ecx
add eax,4
pop ecx ebx
ret
endp
;-----------------------------------------------------------------------------
proc mem.ReAlloc mptr,size;///////////////////////////////////////////////////
;-----------------------------------------------------------------------------
push ebx ecx esi edi eax
mov eax,[mptr]
mov ebx,[size]
or eax,eax
jz @f
lea ecx,[ebx+4+4095]
and ecx,not 4095
add ecx,-4
cmp ecx,[eax-4]
je .exit
@@: mov eax,ebx
call mem.Alloc
xchg eax,[esp]
or eax,eax
jz .exit
mov esi,eax
xchg eax,[esp]
mov edi,eax
mov ecx,[esi-4]
cmp ecx,[edi-4]
jbe @f
mov ecx,[edi-4]
@@: add ecx,3
shr ecx,2
cld
rep movsd
xchg eax,[esp]
call mem.Free
.exit:
pop eax edi esi ecx ebx
ret
endp
;-----------------------------------------------------------------------------
proc mem.Free mptr ;//////////////////////////////////////////////////////////
;-----------------------------------------------------------------------------
mov eax,[mptr]
or eax,eax
jz @f
push ebx ecx
lea ecx,[eax-4]
mcall 68,13
pop ecx ebx
@@: ret
endp
proc dll.Load, import_table:dword
mov esi,[import_table]
.next_lib: mov edx,[esi]
or edx,edx
jz .exit
push esi
mov esi,[esi+4]
mov edi,s_libdir.fname
@@: lodsb
stosb
or al,al
jnz @b
mcall 68,19,s_libdir
or eax,eax
jz .fail
stdcall dll.Link,eax,edx
stdcall dll.Init,[eax+4]
pop esi
add esi,8
jmp .next_lib
.exit: xor eax,eax
ret
.fail: add esp,4
xor eax,eax
inc eax
ret
endp
proc dll.Link, exp:dword,imp:dword
push eax
mov esi,[imp]
test esi,esi
jz .done
.next: lodsd
test eax,eax
jz .done
stdcall dll.GetProcAddress,[exp],eax
or eax,eax
jz @f
mov [esi-4],eax
jmp .next
@@: mov dword[esp],0
.done: pop eax
ret
endp
proc dll.Init, dllentry:dword
pushad
mov eax,mem.Alloc
mov ebx,mem.Free
mov ecx,mem.ReAlloc
mov edx,dll.Load
stdcall [dllentry]
popad
ret
endp
proc dll.GetProcAddress, exp:dword,sz_name:dword
mov edx,[exp]
xor eax,eax
.next: or edx,edx
jz .end
cmp dword[edx],0
jz .end
stdcall strcmp,[edx],[sz_name]
test eax,eax
jz .ok
add edx,8
jmp .next
.ok: mov eax,[edx+4]
.end: ret
endp
proc strcmp, str1:dword,str2:dword
push esi edi
mov esi,[str1]
mov edi,[str2]
xor eax,eax
@@: lodsb
scasb
jne .fail
or al,al
jnz @b
jmp .ok
.fail: or eax,-1
.ok: pop edi esi
ret
endp
s_libdir:
db '/sys/lib/'
.fname rb 32

View File

@ -15,7 +15,7 @@ BUFFERSIZE equ 1500
include '../macros.inc' include '../macros.inc'
purge mov,add,sub purge mov,add,sub
include '../proc32.inc' include '../proc32.inc'
include 'dll.inc' include '../dll.inc'
include '../network.inc' include '../network.inc'

View File

@ -308,12 +308,7 @@ proc service_proc stdcall, ioctl:dword
cmp [devices], MAX_DEVICES ; First check if the driver can handle one more card cmp [devices], MAX_DEVICES ; First check if the driver can handle one more card
jge .fail jge .fail
push edx allocate_and_clear ebx, device.size, .fail ; Allocate the buffer for device structure
stdcall KernelAlloc, device.size ; Allocate the buffer for eth_device structure
pop edx
test eax, eax
jz .fail
mov ebx, eax ; ebx is always used as a pointer to the structure (in driver, but also in kernel code)
; Fill in the direct call addresses into the struct ; Fill in the direct call addresses into the struct
@ -619,20 +614,21 @@ reset:
mov eax, [device.rx_buffer] mov eax, [device.rx_buffer]
call GetPgAddr call GetPgAddr
set_io 0 ; set_io 0
set_io REG_RBSTART set_io REG_RBSTART
out dx , eax out dx , eax
; enable interrupts
mov eax, INTERRUPT_MASK
set_io REG_IMR
out dx , ax
; Read MAC address ; Read MAC address
call read_mac call read_mac
; enable interrupts
set_io 0
set_io REG_IMR
mov eax, INTERRUPT_MASK
out dx , ax
; Set the mtu, kernel will be able to send now ; Set the mtu, kernel will be able to send now
mov [device.mtu], 1514 mov [device.mtu], 1514
@ -724,7 +720,7 @@ transmit:
.fail: .fail:
DEBUGF 1,"failed!\n" DEBUGF 1,"failed!\n"
or eax, -1 stdcall KernelFree, [esp+4]
ret 8 ret 8
@ -890,6 +886,8 @@ int_handler:
test ax, ISR_TER test ax, ISR_TER
jz @f jz @f
DEBUGF 1,"Transmit error\n"
; push ax ; push ax
; cmp [device.curr_tx_desc], 4 ; cmp [device.curr_tx_desc], 4
; jz .notxd ; jz .notxd
@ -1114,85 +1112,6 @@ read_mac:
ret ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Read eeprom (type 93c46 and 93c56) ;;
;; ;;
;; In: word to be read in al (6bit in case of 93c46 and 8bit otherwise) ;;
;; pointer to device structure in ebx ;;
;; ;;
;; OUT: word read in ax ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
align 4
read_eeprom:
DEBUGF 2,"Reading eeprom, "
set_io 0
push ebx
movzx ebx, al
set_io REG_RXCONFIG
in al, dx
test al, (1 shl BIT_9356SEL)
jz .type_93c46
; and bl, 01111111b ; don't care first bit
or bx, EE_93C56_READ_CMD ; it contains start bit
mov cx, EE_93C56_CMD_LENGTH-1 ; cmd_loop counter
jmp .read_eeprom
.type_93c46:
and bl, 00111111b
or bx, EE_93C46_READ_CMD ; it contains start bit
mov cx, EE_93C46_CMD_LENGTH-1 ; cmd_loop counter
.read_eeprom:
set_io REG_9346CR
; mov al, (1 shl BIT_93C46_EEM1)
; out dx, al
mov al, (1 shl BIT_93C46_EEM1) or (1 shl BIT_93C46_EECS) ; wake up the eeprom
out dx, al
.cmd_loop:
mov al, (1 shl BIT_93C46_EEM1) or (1 shl BIT_93C46_EECS)
bt bx, cx
jnc .zero_bit
or al, (1 shl BIT_93C46_EEDI)
.zero_bit:
out dx, al
; push eax
; in eax, dx ; eeprom delay
; pop eax
or al, (1 shl BIT_93C46_EESK)
out dx, al
; in eax, dx ; eeprom delay
dec cx
jns .cmd_loop
; in eax, dx ; eeprom delay
mov al, (1 shl BIT_93C46_EEM1) or (1 shl BIT_93C46_EECS)
out dx, al
mov cl, 0xf
.read_loop:
shl ebx, 1
mov al, (1 shl BIT_93C46_EEM1) or (1 shl BIT_93C46_EECS) or (1 shl BIT_93C46_EESK)
out dx, al
; in eax, dx ; eeprom delay
in al, dx
and al, (1 shl BIT_93C46_EEDO)
jz .dont_set
inc ebx
.dont_set:
mov al, (1 shl BIT_93C46_EEM1) or (1 shl BIT_93C46_EECS)
out dx, al
; in eax, dx ; eeprom delay
dec cl
jns .read_loop
xor al, al
out dx, al
mov ax, bx
pop ebx
ret
; End of code ; End of code
section '.data' data readable writable align 16 ; place all uninitialized data place here section '.data' data readable writable align 16 ; place all uninitialized data place here

View File

@ -994,16 +994,14 @@ transmit:
DEBUGF 1,"transmit ok\n" DEBUGF 1,"transmit ok\n"
xor eax, eax xor eax, eax
call Kernelfree stdcall KernelFree, [esp+4]
add esp, 4 ret 8
ret
.fail: .fail:
DEBUGF 1,"transmit failed\n" DEBUGF 1,"transmit failed\n"
or eax, -1 or eax, -1
call Kernelfree stdcall KernelFree, [esp+4]
add esp, 4 ret 8
ret
;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;

View File

@ -23,6 +23,10 @@ format MS COFF
__DEBUG__ equ 1 __DEBUG__ equ 1
__DEBUG_LEVEL__ equ 1 __DEBUG_LEVEL__ equ 1
TX_RING_SIZE equ 4
RX_RING_SIZE equ 4
PKT_BUF_SZ equ 1544
include 'proc32.inc' include 'proc32.inc'
include 'imports.inc' include 'imports.inc'
@ -33,6 +37,19 @@ public START
public service_proc public service_proc
public version public version
struc buf_head {
.base dd ?
.length dw ?
.status dw ?
.msg_length dw ?
.misc dw ?
.reserved dd ?
.size:
}
virtual at 0
buf_head buf_head
end virtual
virtual at ebx virtual at ebx
@ -57,8 +74,8 @@ virtual at ebx
.access_write_rap dd ? .access_write_rap dd ?
.access_reset dd ? .access_reset dd ?
; The following fields up to .tx_ring_phys inclusive form ; The following fields up to .tx_ring_phys inclusive form
; initialization block for hardware; do not modify (must be 4-aligned) ; initialization block for hardware; do not modify (must be 4-aligned)
.private: .private:
.mode_ dw ? .mode_ dw ?
@ -68,8 +85,10 @@ virtual at ebx
.filter dq ? .filter dq ?
.rx_ring_phys dd ? .rx_ring_phys dd ?
.tx_ring_phys dd ? .tx_ring_phys dd ?
.rx_ring dd ?
.tx_ring dd ? .rx_ring rb RX_RING_SIZE * buf_head.size
.tx_ring rb TX_RING_SIZE * buf_head.size
.cur_rx db ? .cur_rx db ?
.cur_tx db ? .cur_tx db ?
.dirty_rx dd ? .dirty_rx dd ?
@ -88,20 +107,6 @@ virtual at ebx
end virtual end virtual
struc buf_head {
.base dd ?
.length dw ?
.status dw ?
.msg_length dw ?
.misc dw ?
.reserved dd ?
.size:
}
virtual at 0
buf_head buf_head
end virtual
struc rx_desc_2 { ; Swstyle 2 struc rx_desc_2 { ; Swstyle 2
@ -147,9 +152,6 @@ virtual at 0
rx_desc rx_desc_2 rx_desc rx_desc_2
end virtual end virtual
; PCI Bus defines
PORT_AUI equ 0x00 PORT_AUI equ 0x00
PORT_10BT equ 0x01 PORT_10BT equ 0x01
PORT_GPSI equ 0x02 PORT_GPSI equ 0x02
@ -164,17 +166,12 @@ end virtual
LOG_TX_BUFFERS equ 2 LOG_TX_BUFFERS equ 2
LOG_RX_BUFFERS equ 2 LOG_RX_BUFFERS equ 2
TX_RING_SIZE equ 4
TX_RING_MOD_MASK equ (TX_RING_SIZE-1) TX_RING_MOD_MASK equ (TX_RING_SIZE-1)
TX_RING_LEN_BITS equ (LOG_TX_BUFFERS shl 12) TX_RING_LEN_BITS equ (LOG_TX_BUFFERS shl 12)
RX_RING_SIZE equ 4
RX_RING_MOD_MASK equ (RX_RING_SIZE-1) RX_RING_MOD_MASK equ (RX_RING_SIZE-1)
RX_RING_LEN_BITS equ (LOG_RX_BUFFERS shl 4) RX_RING_LEN_BITS equ (LOG_RX_BUFFERS shl 4)
PKT_BUF_SZ equ 1544
PKT_BUF_SZ_NEG equ 0xf9f8
WIO_RDP equ 0x10 WIO_RDP equ 0x10
WIO_RAP equ 0x12 WIO_RAP equ 0x12
WIO_RESET equ 0x14 WIO_RESET equ 0x14
@ -518,19 +515,8 @@ proc service_proc stdcall, ioctl:dword
DEBUGF 1,"Hooking into device, dev:%x, bus:%x, irq:%x, addr:%x\n",\ DEBUGF 1,"Hooking into device, dev:%x, bus:%x, irq:%x, addr:%x\n",\
[device.pci_dev]:1,[device.pci_bus]:1,[device.irq_line]:1,[device.io_addr]:4 [device.pci_dev]:1,[device.pci_bus]:1,[device.irq_line]:1,[device.io_addr]:4
;;; allocate_and_clear [device.tx_buffer], (RX_RING_SIZE * PKT_BUF_SZ), .err allocate_and_clear [device.tx_buffer], (RX_RING_SIZE * PKT_BUF_SZ), .err
allocate_and_clear [device.rx_buffer], (TX_RING_SIZE * PKT_BUF_SZ), .err allocate_and_clear [device.rx_buffer], (TX_RING_SIZE * PKT_BUF_SZ), .err
allocate_and_clear [device.rx_ring], (RX_RING_SIZE * buf_head.size), .err
mov eax, [device.rx_ring]
call GetPgAddr
mov [device.rx_ring_phys], eax
allocate_and_clear [device.tx_ring], (TX_RING_SIZE * buf_head.size), .err
mov eax, [device.tx_ring]
call GetPgAddr
mov [device.tx_ring_phys], eax
; Ok, the eth_device structure is ready, let's probe the device ; Ok, the eth_device structure is ready, let's probe the device
; Because initialization fires IRQ, IRQ handler must be aware of this device ; Because initialization fires IRQ, IRQ handler must be aware of this device
@ -569,7 +555,7 @@ proc service_proc stdcall, ioctl:dword
.err: .err:
DEBUGF 1,"Error, removing all data !\n" DEBUGF 1,"Error, removing all data !\n"
stdcall KernelFree, [device.rx_buffer] stdcall KernelFree, [device.rx_buffer]
;;; stdcall KernelFree, [device.tx_buffer] stdcall KernelFree, [device.tx_buffer]
stdcall KernelFree, ebx stdcall KernelFree, ebx
.fail: .fail:
@ -610,26 +596,33 @@ ret
align 4 align 4
probe: probe:
; make the device a bus master
make_bus_master [device.pci_bus], [device.pci_dev] make_bus_master [device.pci_bus], [device.pci_dev]
; first, fill in some of the structure variables ; create the RX-ring
mov edi, [device.rx_ring] lea edi, [device.rx_ring]
mov ecx, RX_RING_SIZE mov ecx, RX_RING_SIZE
mov eax, [device.rx_buffer] mov eax, [device.rx_buffer]
call GetPgAddr call GetPgAddr
.rx_init: .rx_init:
mov [edi + buf_head.base], eax mov [edi + buf_head.base], eax
mov [edi + buf_head.length], PKT_BUF_SZ_NEG mov [edi + buf_head.length], - PKT_BUF_SZ
mov [edi + buf_head.status], 0x8000 mov [edi + buf_head.status], 0x8000
and dword [edi + buf_head.msg_length], 0 and dword [edi + buf_head.msg_length], 0
and dword [edi + buf_head.reserved], 0 and dword [edi + buf_head.reserved], 0
add eax, PKT_BUF_SZ add eax, PKT_BUF_SZ
; inc eax add edi, buf_head.size
add edi, buf_head.size loop .rx_init
loop .rx_init
mov edi, [device.tx_ring] lea eax, [device.rx_ring]
GetRealAddr
mov [device.rx_ring_phys], eax
; create the Tx-ring
lea edi, [device.tx_ring]
mov ecx, TX_RING_SIZE mov ecx, TX_RING_SIZE
mov eax, [device.tx_buffer] mov eax, [device.tx_buffer]
call GetPgAddr call GetPgAddr
@ -642,9 +635,13 @@ probe:
add edi, buf_head.size add edi, buf_head.size
loop .tx_init loop .tx_init
lea eax, [device.tx_ring]
GetRealAddr
mov [device.tx_ring_phys], eax
mov [device.tlen_rlen], (TX_RING_LEN_BITS or RX_RING_LEN_BITS) mov [device.tlen_rlen], (TX_RING_LEN_BITS or RX_RING_LEN_BITS)
; First, we must try to use Word operations ; First, we must try to use Word operations
call switch_to_wio call switch_to_wio
set_io 0 set_io 0
call wio_reset call wio_reset
@ -655,22 +652,23 @@ probe:
jne .try_dwio jne .try_dwio
; Try Word I/O ; Try Word I/O
mov ax , 88 mov ax, 88
add edx, WIO_RAP set_io WIO_RAP
out dx , ax out dx, ax
nop nop
nop nop
in ax , dx in ax, dx
sub edx, WIO_RAP set_io 0
cmp ax , 88 cmp ax, 88
jne .try_dwio jne .try_dwio
DEBUGF 1,"Using WIO\n" DEBUGF 1,"Using WIO\n"
call switch_to_wio call switch_to_wio
jmp .L1 jmp .L1
; If WIO fails, try to use DWIO
.try_dwio: .try_dwio:
call dwio_reset call dwio_reset
@ -683,27 +681,27 @@ probe:
; Try Dword I/O ; Try Dword I/O
set_io DWIO_RAP set_io DWIO_RAP
mov eax, 88 mov eax, 88
out dx , eax out dx, eax
nop nop
nop nop
in eax, dx in eax, dx
set_io 0 set_io 0
and eax, 0xffff cmp ax, 88
cmp eax, 88
jne .no_dev jne .no_dev
DEBUGF 1,"Using DWIO\n" DEBUGF 1,"Using DWIO\n"
call switch_to_dwio call switch_to_dwio
jmp .L1 jmp .L1
; If both methods fail, something is wrong!
.no_dev: .no_dev:
DEBUGF 1,"PCnet device not found!\n" DEBUGF 1,"PCnet device not found!\n"
mov eax, 1 mov eax, -1
ret ret
.L1:
.L1:
mov ecx, CSR_CHIPID0 mov ecx, CSR_CHIPID0
call [device.access_read_csr] call [device.access_read_csr]
mov esi, eax mov esi, eax
@ -722,7 +720,8 @@ probe:
and eax, 0xffff and eax, 0xffff
mov [device.chip_version], eax mov [device.chip_version], eax
DEBUGF 1,"chip version ok\n" DEBUGF 1,"chip version: %x\n", eax
mov [device.fdx], 0 mov [device.fdx], 0
mov [device.mii], 0 mov [device.mii], 0
mov [device.fset], 0 mov [device.fset], 0
@ -749,7 +748,7 @@ probe:
cmp eax, 0x2627 cmp eax, 0x2627
je .L9 je .L9
DEBUGF 1,"Invalid chip rev\n" DEBUGF 1,"Invalid chip rev\n"
jmp .no_dev jmp .no_dev
.L2: .L2:
mov [device.name], device_l2 mov [device.name], device_l2
@ -788,19 +787,17 @@ probe:
; mov [device.fdx], 1 ; mov [device.fdx], 1
mov [device.mii], 1 mov [device.mii], 1
.L10: .L10:
DEBUGF 1,"device name: %s\n",[device.name] DEBUGF 1,"device name: %s\n",[device.name]
cmp [device.fset], 1 cmp [device.fset], 1
jne .L11 jne .L11
mov ecx, BCR_BUSCTL mov ecx, BCR_BUSCTL
call [device.access_read_bcr] call [device.access_read_bcr]
or eax, 0x800 or ax, 0x800
call [device.access_write_bcr] call [device.access_write_bcr]
mov ecx, CSR_DMACTL mov ecx, CSR_DMACTL
call [device.access_read_csr] call [device.access_read_csr]
; and eax, 0xc00
; or eax, 0xc00
mov eax, 0xc00 mov eax, 0xc00
call [device.access_write_csr] call [device.access_write_csr]
@ -808,8 +805,7 @@ probe:
mov [device.ltint],1 mov [device.ltint],1
.L11: .L11:
DEBUGF 1,"PCI done\n" mov eax, PORT_ASEL ; Auto-select
mov eax, PORT_ASEL
mov [device.options], eax mov [device.options], eax
mov [device.mode_], word 0x0003 mov [device.mode_], word 0x0003
mov [device.tlen_rlen], word (TX_RING_LEN_BITS or RX_RING_LEN_BITS) mov [device.tlen_rlen], word (TX_RING_LEN_BITS or RX_RING_LEN_BITS)
@ -818,16 +814,15 @@ probe:
mov dword [device.filter+4], 0 mov dword [device.filter+4], 0
mov eax, IMR mov eax, IMR
mov ecx, CSR_IMR ; Write interrupt mask mov ecx, CSR_IMR ; Write interrupt mask
call [device.access_write_csr] call [device.access_write_csr]
align 4 align 4
reset: reset:
DEBUGF 1,"Resetting PCnet device: %x\n", ebx
; attach int handler ; attach int handler
movzx eax, [device.irq_line] movzx eax, [device.irq_line]
@ -845,10 +840,10 @@ reset:
; Switch to dword operations ; Switch to dword operations
DEBUGF 1,"Switching to 32-bit mode\n" DEBUGF 1,"Switching to 32-bit mode\n"
mov ecx, DWIO_RDP mov ecx, DWIO_RDP
mov eax, 0 xor eax, eax
call wio_write_csr call wio_write_csr
call switch_to_dwio call switch_to_dwio
@ -858,28 +853,31 @@ reset:
set_io 0 set_io 0
set_io DWIO_RAP set_io DWIO_RAP
mov eax, 88 mov eax, 88
out dx , eax out dx, eax
nop nop
nop nop
in eax, dx in eax, dx
set_io 0 set_io 0
and eax, 0xffff cmp ax, 88
cmp eax, 88
je .yes_dwio je .yes_dwio
call switch_to_wio ; it seem to have failed, reset device again and use wio call switch_to_wio ; it seems to have failed, reset device again and use wio
set_io 0 set_io 0
call [device.access_reset] call [device.access_reset]
.yes_dwio: .yes_dwio:
set_io 0
mov ecx, BCR_SSTYLE ; Select Software style 2 ;;;
mov eax, 2
call [device.access_write_bcr]
; set/reset autoselect bit ; set/reset autoselect bit
mov ecx, BCR_MISCCFG mov ecx, BCR_MISCCFG
call [device.access_read_bcr] call [device.access_read_bcr]
and eax,not 2
test [device.options], PORT_ASEL test [device.options], PORT_ASEL
jz .L1 jnz .L1
or eax, 2 and eax, not 2
.L1: .L1:
call [device.access_write_bcr] call [device.access_write_bcr]
@ -940,7 +938,7 @@ reset:
test [device.options], PORT_ASEL test [device.options], PORT_ASEL
jz .L9 jz .L9
mov ecx, BCR_MIICTL mov ecx, BCR_MIICTL
DEBUGF 1,"ASEL, enable auto-negotiation\n" DEBUGF 1,"ASEL, enable auto-negotiation\n"
call [device.access_read_bcr] call [device.access_read_bcr]
and eax, not 0x98 and eax, not 0x98
or eax, 0x20 or eax, 0x20
@ -968,41 +966,41 @@ reset:
movsw movsw
lea eax, [device.private] lea eax, [device.private]
mov ecx, eax GetRealAddr
and ecx, 0xFFF ; KolibriOS PAGE SIZE
call GetPgAddr
add eax, ecx
push eax push eax
and eax, 0xffff and eax, 0xffff
mov ecx, 1 mov ecx, 1
call [device.access_write_csr] call [device.access_write_csr]
pop eax pop eax
shr eax,16 shr eax, 16
mov ecx,2 mov ecx, 2
call [device.access_write_csr] call [device.access_write_csr]
mov ecx,4 mov ecx, 4
mov eax,0x0915 mov eax, 0x0915
call [device.access_write_csr] call [device.access_write_csr]
mov ecx,0 xor ecx, ecx
mov eax,1 mov eax, 1
call [device.access_write_csr] call [device.access_write_csr]
mov [device.tx_full],0 mov [device.tx_full], 0
mov [device.cur_rx],0 mov [device.cur_rx], 0
mov [device.cur_tx],0 mov [device.cur_tx], 0
mov [device.dirty_rx],0 mov [device.dirty_rx], 0
mov [device.dirty_tx],0 mov [device.dirty_tx], 0
mov ecx,100 mov ecx, 100
.L11: .L11:
push ecx push ecx
xor ecx, ecx xor ecx, ecx
call [device.access_read_csr] call [device.access_read_csr]
pop ecx pop ecx
test ax,0x100 push esi
mov esi, 100
call Sleep
pop esi
test ax, 0x100
jnz .L12 jnz .L12
loop .L11 loop .L11
.L12: .L12:
@ -1046,7 +1044,7 @@ reset:
align 4 align 4
transmit: transmit:
DEBUGF 1,"Transmitting packet, buffer:%x, size:%u\n",[esp+4],[esp+8] DEBUGF 1,"Transmitting packet, buffer:%x, size:%u\n", [esp+4], [esp+8]
mov eax, [esp+4] mov eax, [esp+4]
DEBUGF 1,"To: %x-%x-%x-%x-%x-%x From: %x-%x-%x-%x-%x-%x Type:%x%x\n",\ DEBUGF 1,"To: %x-%x-%x-%x-%x-%x From: %x-%x-%x-%x-%x-%x Type:%x%x\n",\
[eax+00]:2,[eax+01]:2,[eax+02]:2,[eax+03]:2,[eax+04]:2,[eax+05]:2,\ [eax+00]:2,[eax+01]:2,[eax+02]:2,[eax+03]:2,[eax+04]:2,[eax+05]:2,\
@ -1063,7 +1061,9 @@ transmit:
imul edi, eax, PKT_BUF_SZ imul edi, eax, PKT_BUF_SZ
shl eax, 4 shl eax, 4
add edi, [device.tx_buffer] add edi, [device.tx_buffer]
add eax, [device.tx_ring]
lea eax, [eax + device.tx_ring]
test byte [eax + buf_head.status + 1], 80h test byte [eax + buf_head.status + 1], 80h
jnz .nospace jnz .nospace
@ -1104,17 +1104,15 @@ transmit:
adc dword [device.bytes_tx + 4], 0 adc dword [device.bytes_tx + 4], 0
DEBUGF 2," - Done!\n" DEBUGF 2," - Done!\n"
call Kernelfree stdcall KernelFree, [esp+4]
add esp, 4 ret 8
ret
.nospace: .nospace:
DEBUGF 1, 'ERROR: no free transmit descriptors\n' DEBUGF 1, 'ERROR: no free transmit descriptors\n'
; todo: maybe somehow notify the kernel about the error? ; todo: maybe somehow notify the kernel about the error?
call Kernelfree stdcall KernelFree, [esp+4]
add esp, 4 ret 8
ret
@ -1127,7 +1125,7 @@ transmit:
align 4 align 4
int_handler: int_handler:
DEBUGF 1,"IRQ %x ", eax:2 ; no, you cant replace 'eax:2' with 'al', this must be a bug in FDO DEBUGF 1,"IRQ=%x ", eax:2 ; no, you cant replace 'eax:2' with 'al', this must be a bug in FDO
; find pointer of device wich made IRQ occur ; find pointer of device wich made IRQ occur
@ -1137,7 +1135,6 @@ int_handler:
jz .abort jz .abort
.nextdevice: .nextdevice:
mov ebx, [esi] mov ebx, [esi]
DEBUGF 1,"device=%x? ", ebx
set_io 0 set_io 0
push ecx push ecx
@ -1154,7 +1151,7 @@ int_handler:
ret ; If no device was found, abort (The irq was probably for a device, not registered to this driver ret ; If no device was found, abort (The irq was probably for a device, not registered to this driver
.got_it: .got_it:
DEBUGF 1,"yes, reason=%x ", ax DEBUGF 1,"csr=%x\n", ax
;------------------------------------------------------- ;-------------------------------------------------------
; Possible reasons: ; Possible reasons:
; initialization done - ignore ; initialization done - ignore
@ -1170,7 +1167,11 @@ int_handler:
test ax, CSR_RINT test ax, CSR_RINT
jz @f jz @f
.receiver_test_loop: push ax
DEBUGF 1,"packet received!\n"
.receiver_test_loop:
movzx eax, [device.cur_rx] movzx eax, [device.cur_rx]
; and eax, RX_RING_MOD_MASK ; and eax, RX_RING_MOD_MASK
mov edi, eax mov edi, eax
@ -1179,7 +1180,7 @@ int_handler:
add esi, [device.rx_buffer] ; esi now points to rx buffer add esi, [device.rx_buffer] ; esi now points to rx buffer
shl edi, 4 ; desc * 16 (16 is size of one ring entry) shl edi, 4 ; desc * 16 (16 is size of one ring entry)
add edi, [device.rx_ring] ; edi now points to current rx ring entry lea edi, [edi + device.rx_ring] ; edi now points to current rx ring entry
mov cx , [edi + buf_head.status] mov cx , [edi + buf_head.status]
@ -1234,9 +1235,25 @@ int_handler:
jmp EthReceiver ; Send the copied packet to kernel jmp EthReceiver ; Send the copied packet to kernel
.abort: .abort:
DEBUGF 1,"done \n" pop ax
@@: @@:
test ax, IMR_TINT
jz @f
DEBUGF 1,"Transmit OK!\n"
@@:
test ax, IMR_MISS
jz @f
DEBUGF 1,"We missed a frame! (RX ring full?)\n"
@@:
DEBUGF 1,"done\n"
ret ret
@ -1253,10 +1270,9 @@ write_mac: ; in: mac pushed onto stack (as 3 words)
DEBUGF 1,"Writing MAC: %x-%x-%x-%x-%x-%x",[esp+0]:2,[esp+1]:2,[esp+2]:2,[esp+3]:2,[esp+4]:2,[esp+5]:2 DEBUGF 1,"Writing MAC: %x-%x-%x-%x-%x-%x",[esp+0]:2,[esp+1]:2,[esp+2]:2,[esp+3]:2,[esp+4]:2,[esp+5]:2
mov edx, [device.io_addr] set_io 0
add edx, 2 ; set_io 2
xor eax, eax xor eax, eax
mov ecx, CSR_PAR0 mov ecx, CSR_PAR0
@@: @@:
pop ax pop ax
@ -1279,8 +1295,8 @@ write_mac: ; in: mac pushed onto stack (as 3 words)
read_mac: read_mac:
DEBUGF 1,"Reading MAC" DEBUGF 1,"Reading MAC"
mov edx, [device.io_addr] set_io 0
add edx, 6 set_io 6
@@: @@:
dec dx dec dx
dec dx dec dx
@ -1518,11 +1534,11 @@ dwio_reset:
; End of code ; End of code
align 4 ; Place all initialised data here align 4 ; Place all initialised data here
devices dd 0 devices dd 0
version dd (DRIVER_VERSION shl 16) or (API_VERSION and 0xFFFF) version dd (DRIVER_VERSION shl 16) or (API_VERSION and 0xFFFF)
my_service db 'PCnet32',0 ; max 16 chars include zero my_service db 'PCnet',0 ; max 16 chars include zero
device_l2 db "PCnet/PCI 79C970",0 device_l2 db "PCnet/PCI 79C970",0
device_l4 db "PCnet/PCI II 79C970A",0 device_l4 db "PCnet/PCI II 79C970A",0

View File

@ -1275,7 +1275,7 @@ transmit:
add dword [device.bytes_tx], ecx add dword [device.bytes_tx], ecx
adc dword [device.bytes_tx+4], 0 adc dword [device.bytes_tx+4], 0
ret ret 8
; End of code ; End of code

View File

@ -653,6 +653,94 @@ IPv4_output:
ret ret
;------------------------------------------------------------------
;
; IPv4_output_raw
;
; IN: eax = socket ptr
; ecx = data length
; esi = data ptr
;
; OUT: /
;
;------------------------------------------------------------------
align 4
IPv4_output_raw:
DEBUGF 1,"IPv4_output_raw: size=%u ptr=%x socket=%x\n", ecx, esi, eax
cmp ecx, 1480 ;;;;;
jg .too_large
sub esp, 8
push esi eax
call ARP_IP_to_MAC
test eax, 0xffff0000 ; error bits
jnz .arp_error
.continue:
push ebx ; push the mac
push ax
call IPv4_dest_to_dev
inc [IP_PACKETS_TX+edi]
mov ebx, [NET_DRV_LIST+edi]
lea eax, [ebx + ETH_DEVICE.mac]
mov edx, esp
mov ecx, [esp + 6+4]
add ecx, IPv4_Packet.DataOrOptional
mov di, ETHER_IPv4
call ETH_output
jz .error
add esp, 6 ; pop the mac
mov dword[esp+4+4], edx
mov dword[esp+4+4+4], eax
pop eax esi
;; todo: check socket options if we should add header, or just compute checksum
push edi ecx
rep movsb
pop ecx edi
; [edi + IPv4_Packet.VersionAndIHL] ; IPv4, normal length (no Optional header)
; [edi + IPv4_Packet.TypeOfService] ; nothing special, just plain ip packet
; [edi + IPv4_Packet.TotalLength]
; [edi + IPv4_Packet.TotalLength] ; internet byte order
; [edi + IPv4_Packet.FlagsAndFragmentOffset]
mov [edi + IPv4_Packet.HeaderChecksum], 0
; [edi + IPv4_Packet.TimeToLive] ; ttl shl 8 + protocol
; [edi + IPv4_Packet.Protocol]
; [edi + IPv4_Packet.Identification] ; fragment id
; [edi + IPv4_Packet.SourceAddress]
; [edi + IPv4_Packet.DestinationAddress]
IPv4_checksum edi ;;;; todo: checksum for IP packet with options!
add edi, IPv4_Packet.DataOrOptional
DEBUGF 1,"IPv4 Packet for device %x created successfully\n", ebx
call [ebx + NET_DEVICE.transmit]
ret
.error:
add esp, 6
.arp_error:
add esp, 8+4+4
.too_large:
DEBUGF 1,"IPv4_output_raw: Failed\n"
sub edi, edi
ret
;-------------------------------------------------------- ;--------------------------------------------------------
; ;
; ;

View File

@ -132,24 +132,24 @@ macro ICMP_init {
; ;
; IN: Pointer to buffer in [esp] ; IN: Pointer to buffer in [esp]
; size of buffer in [esp+4] ; size of buffer in [esp+4]
; pointer to device struct in ebx ; ebx = pointer to device struct
; ICMP Packet size in ecx ; ecx = ICMP Packet size
; pointer to ICMP Packet data in edx ; edx = ptr to ICMP Packet data
; esi = ipv4 source address
; edi = ipv4 dest address
; OUT: / ; OUT: /
; ;
;----------------------------------------------------------------- ;-----------------------------------------------------------------
align 4 align 4
ICMP_input: ICMP_input:
;;; TODO: works only on pure ethernet right now ! ;;; TODO: check checksum!
DEBUGF 1,"ICMP_Handler - start\n" DEBUGF 1,"ICMP_input - start\n"
cmp byte [edx + ICMP_Packet.Type], ICMP_ECHO ; Is this an echo request? cmp byte [edx + ICMP_Packet.Type], ICMP_ECHO ; Is this an echo request?
jne .check_sockets jne .check_sockets
;;; TODO: check checksum! DEBUGF 1,"ICMP_input - echo request\n"
DEBUGF 1,"ICMP_Handler - echo request\n"
mov byte [edx + ICMP_Packet.Type], ICMP_ECHOREPLY ; Change Packet type to reply mov byte [edx + ICMP_Packet.Type], ICMP_ECHOREPLY ; Change Packet type to reply
mov word [edx + ICMP_Packet.Checksum], 0 ; Set checksum to 0, needed to calculate new checksum mov word [edx + ICMP_Packet.Checksum], 0 ; Set checksum to 0, needed to calculate new checksum
@ -211,43 +211,47 @@ ICMP_input:
.check_sockets: .check_sockets:
; TODO: validate the header & checksum.
; Look for an open ICMP socket ; Look for an open ICMP socket
; esi = sender ip
mov esi, net_sockets mov ebx, net_sockets
.try_more: .try_more:
mov ax , [edx + ICMP_Packet.Identifier] ; mov ax , [edx + ICMP_Packet.Identifier]
.next_socket: .next_socket:
mov esi, [esi + SOCKET.NextPtr] mov ebx, [ebx + SOCKET.NextPtr]
or esi, esi or ebx, ebx
jz .dump jz .dump
cmp [esi + SOCKET.Type], IP_PROTO_ICMP
jne .next_socket cmp [ebx + SOCKET.Domain], AF_INET4
cmp [esi + ICMP_SOCKET.Identifier], ax
jne .next_socket jne .next_socket
call IPv4_dest_to_dev cmp [ebx + SOCKET.Type], SOCK_RAW
cmp edi,-1 jne .next_socket
je .dump
inc [ICMP_PACKETS_RX+edi]
DEBUGF 1,"Found valid ICMP packet for socket %x\n", esi cmp [ebx + SOCKET.Protocol], IP_PROTO_ICMP
jne .next_socket
lea ebx, [esi + SOCKET.lock] cmp [ebx + IP_SOCKET.RemoteIP], esi
jne .next_socket
; cmp [esi + ICMP_SOCKET.Identifier], ax
; jne .next_socket
; call IPv4_dest_to_dev
; cmp edi,-1
; je .dump
; inc [ICMP_PACKETS_RX+edi]
DEBUGF 1,"Found valid ICMP packet for socket %x\n", ebx
mov eax, ebx
add ebx, SOCKET.lock
call wait_mutex call wait_mutex
; Now, assign data to socket. We have socket address in esi. mov esi, edx
; We have ICMP Packet in edx
; number of bytes in ecx
mov eax, esi
pop esi
add esp, 4
sub edx, esi
mov edi, edx
jmp SOCKET_input jmp SOCKET_input
.dump: .dump:
DEBUGF 1,"ICMP_Handler - dumping\n" DEBUGF 1,"ICMP_Handler - dumping\n"
@ -278,6 +282,8 @@ ICMP_output:
push esi edi edx push esi edi edx
mov ebx, [eax + IP_SOCKET.LocalIP]
mov eax, [eax + IP_SOCKET.RemoteIP]
add ecx, ICMP_Packet.Data add ecx, ICMP_Packet.Data
mov di , IP_PROTO_ICMP SHL 8 + 128 ; TTL mov di , IP_PROTO_ICMP SHL 8 + 128 ; TTL
shr edx, 16 shr edx, 16
@ -325,6 +331,57 @@ ICMP_output:
;-----------------------------------------------------------------
;
; ICMP_output
;
; IN: eax = socket ptr
; ecx = data length
; esi = data offset
;
;-----------------------------------------------------------------
align 4
ICMP_output_raw:
DEBUGF 1,"Creating ICMP Packet for socket %x, data ptr=%x\n", eax, edx
push edx
mov di, IP_PROTO_ICMP SHL 8 + 128 ; TTL
shr edx, 16
mov ebx, [eax + IP_SOCKET.LocalIP]
mov eax, [eax + IP_SOCKET.RemoteIP]
call IPv4_output
jz .exit
pop esi
push edx
push eax
push edi ecx
DEBUGF 1,"copying %u bytes from %x to %x\n", ecx, esi, edi
rep movsb
pop ecx edi
mov [edi + ICMP_Packet.Checksum], 0
mov esi, edi
xor edx, edx
call checksum_1
call checksum_2
mov [edi + ICMP_Packet.Checksum], dx
DEBUGF 1,"Sending ICMP Packet\n"
call [ebx + NET_DEVICE.transmit]
ret
.exit:
DEBUGF 1,"Creating ICMP Packet failed\n"
add esp, 4
ret
;----------------------------------------------------------------- ;-----------------------------------------------------------------
; ;
; ICMP_API ; ICMP_API

View File

@ -317,6 +317,9 @@ SOCKET_open:
cmp edx, IP_PROTO_TCP cmp edx, IP_PROTO_TCP
je .tcp je .tcp
cmp edx, SOCK_RAW
je .raw
.no_inet4: .no_inet4:
ret ret
@ -340,7 +343,36 @@ SOCKET_open:
pop eax pop eax
mov [eax + SOCKET.snd_proc], SOCKET_send_udp mov [eax + SOCKET.snd_proc], SOCKET_send_udp
mov [eax + SOCKET.rcv_proc], SOCKET_receive_udp mov [eax + SOCKET.rcv_proc], SOCKET_receive_dgram
ret
.raw:
; test esi, esi
; jz .ip
cmp esi, IP_PROTO_ICMP
je .icmp
ret
; .ip:
; push eax
; init_queue (eax + SOCKET_QUEUE_LOCATION)
; pop eax
;
; mov [eax + SOCKET.snd_proc], SOCKET_send_ip
; mov [eax + SOCKET.rcv_proc], SOCKET_receive_dgram
;
; ret
.icmp:
push eax
init_queue (eax + SOCKET_QUEUE_LOCATION)
pop eax
mov [eax + SOCKET.snd_proc], SOCKET_send_icmp
mov [eax + SOCKET.rcv_proc], SOCKET_receive_dgram
ret ret
@ -426,7 +458,7 @@ SOCKET_bind:
align 4 align 4
SOCKET_connect: SOCKET_connect:
DEBUGF 1,"socket_connect: socknum: %u sockaddr: %x, length: %u\n", ecx, edx, esi DEBUGF 1,"SOCKET_connect: socknum: %u sockaddr: %x, length: %u\n", ecx, edx, esi
call SOCKET_num_to_ptr call SOCKET_num_to_ptr
jz s_error jz s_error
@ -447,6 +479,9 @@ SOCKET_connect:
cmp [eax + SOCKET.Type], IP_PROTO_TCP cmp [eax + SOCKET.Type], IP_PROTO_TCP
je .tcp je .tcp
cmp [eax + SOCKET.Type], SOCK_RAW
je .raw
jmp s_error jmp s_error
.udp: .udp:
@ -497,6 +532,13 @@ SOCKET_connect:
mov dword [esp+32], 0 ; success! mov dword [esp+32], 0 ; success!
ret ret
.raw:
push dword [edx + 4]
pop dword [eax + IP_SOCKET.RemoteIP]
mov dword [esp+32], 0 ; success!
ret
;----------------------------------------------------------------- ;-----------------------------------------------------------------
; ;
@ -510,7 +552,7 @@ SOCKET_connect:
align 4 align 4
SOCKET_listen: SOCKET_listen:
DEBUGF 1,"Socket_listen: socknum: %u backlog: %u\n", ecx, edx DEBUGF 1,"SOCKET_listen: socknum: %u backlog: %u\n", ecx, edx
call SOCKET_num_to_ptr call SOCKET_num_to_ptr
jz s_error jz s_error
@ -550,7 +592,7 @@ SOCKET_listen:
align 4 align 4
SOCKET_accept: SOCKET_accept:
DEBUGF 1,"Socket_accept: socknum: %u sockaddr: %x, length: %u\n", ecx, edx, esi DEBUGF 1,"SOCKET_accept: socknum: %u sockaddr: %x, length: %u\n", ecx, edx, esi
call SOCKET_num_to_ptr call SOCKET_num_to_ptr
jz s_error jz s_error
@ -601,7 +643,7 @@ SOCKET_accept:
align 4 align 4
SOCKET_close: SOCKET_close:
DEBUGF 1,"socket_close: socknum: %u\n", ecx DEBUGF 1,"SOCKET_close: socknum: %u\n", ecx
call SOCKET_num_to_ptr call SOCKET_num_to_ptr
jz s_error jz s_error
@ -658,11 +700,10 @@ SOCKET_receive:
jmp [eax + SOCKET.rcv_proc] jmp [eax + SOCKET.rcv_proc]
align 4 align 4
SOCKET_receive_udp: SOCKET_receive_dgram:
DEBUGF 1,"type: UDP\n" DEBUGF 1,"SOCKET_receive: DGRAM\n"
mov ebx, esi mov ebx, esi
mov edi, edx ; addr to buffer mov edi, edx ; addr to buffer
@ -705,7 +746,7 @@ SOCKET_receive_udp:
align 4 align 4
SOCKET_receive_tcp: SOCKET_receive_tcp:
DEBUGF 1,"type: TCP\n" DEBUGF 1,"SOCKET_receive: TCP\n"
mov ecx, esi mov ecx, esi
mov edi, edx mov edi, edx
@ -733,7 +774,7 @@ SOCKET_receive_tcp:
align 4 align 4
SOCKET_send: SOCKET_send:
DEBUGF 1,"SOCKET_send: socknum: %u sockaddr: %x, length: %u, flags: %x, ", ecx, edx, esi, edi DEBUGF 1,"SOCKET_send: socknum: %u data ptr: %x, length: %u, flags: %x, ", ecx, edx, esi, edi
call SOCKET_num_to_ptr call SOCKET_num_to_ptr
jz s_error jz s_error
@ -741,11 +782,10 @@ SOCKET_send:
jmp [eax + SOCKET.snd_proc] jmp [eax + SOCKET.snd_proc]
align 4 align 4
SOCKET_send_udp: SOCKET_send_udp:
DEBUGF 1,"type: UDP\n" DEBUGF 1,"SOCKET_send: UDP\n"
mov ecx, esi mov ecx, esi
mov esi, edx mov esi, edx
@ -759,7 +799,7 @@ SOCKET_send_udp:
align 4 align 4
SOCKET_send_tcp: SOCKET_send_tcp:
DEBUGF 1,"type: TCP\n" DEBUGF 1,"SOCKET_send: TCP\n"
push eax push eax
mov ecx, esi mov ecx, esi
@ -774,6 +814,31 @@ SOCKET_send_tcp:
ret ret
;align 4
;SOCKET_send_ip:
;
; DEBUGF 1,"type: IP\n"
;
; mov ecx, esi
; mov esi, edx
;
; call IPv4_output_raw
;
; mov dword [esp+32], eax
; ret
align 4
SOCKET_send_icmp:
DEBUGF 1,"SOCKET_send: ICMP\n"
mov ecx, esi
call ICMP_output_raw
mov dword [esp+32], 0
ret
;----------------------------------------------------------------- ;-----------------------------------------------------------------
@ -991,13 +1056,13 @@ SOCKET_input:
add_to_queue (eax + SOCKET_QUEUE_LOCATION), SOCKET_QUEUE_SIZE, socket_queue_entry.size, SOCKET_input.full add_to_queue (eax + SOCKET_QUEUE_LOCATION), SOCKET_QUEUE_SIZE, socket_queue_entry.size, SOCKET_input.full
DEBUGF 1,"Queued packet successfully\n" DEBUGF 1,"SOCKET_input: queued packet successfully\n"
add esp, socket_queue_entry.size add esp, socket_queue_entry.size
mov [eax + SOCKET.lock], 0 mov [eax + SOCKET.lock], 0
jmp SOCKET_notify_owner jmp SOCKET_notify_owner
.full: .full:
DEBUGF 2,"Socket %x is full!\n", eax DEBUGF 2,"SOCKET_input: socket %x is full!\n", eax
mov [eax + SOCKET.lock], 0 mov [eax + SOCKET.lock], 0
call kernel_free call kernel_free
add esp, 8 add esp, 8
@ -1049,7 +1114,7 @@ SOCKET_ring_write:
.copy: .copy:
mov edi, [eax + RING_BUFFER.write_ptr] mov edi, [eax + RING_BUFFER.write_ptr]
DEBUGF 2,"Copying %u bytes from %x to %x\n", ecx, esi, edi DEBUGF 2,"SOCKET_ring_write: %u bytes from %x to %x\n", ecx, esi, edi
push ecx push ecx
shr ecx, 1 shr ecx, 1
@ -1087,7 +1152,7 @@ SOCKET_ring_write:
jmp .copy jmp .copy
.full: .full:
DEBUGF 2,"Ring buffer is full!\n" DEBUGF 2,"SOCKET_ring_write: ring buffer is full!\n"
xor ecx, ecx xor ecx, ecx
ret ret
@ -1116,7 +1181,7 @@ SOCKET_ring_read:
.copy: .copy:
mov esi, [eax + RING_BUFFER.read_ptr] mov esi, [eax + RING_BUFFER.read_ptr]
DEBUGF 2,"Copying %u bytes from %x to %x\n", ecx, esi, edi DEBUGF 2,"SOCKET_ring_read: %u bytes from %x to %x\n", ecx, esi, edi
push ecx push ecx
shr ecx, 1 shr ecx, 1
jnc .nb jnc .nb
@ -1334,7 +1399,7 @@ SOCKET_free:
lea ebx, [eax + SOCKET.lock] lea ebx, [eax + SOCKET.lock]
call wait_mutex call wait_mutex
DEBUGF 1, "freeing socket..\n" DEBUGF 1, "SOCKET_free: freeing socket..\n"
cmp [eax + SOCKET.Domain], AF_INET4 cmp [eax + SOCKET.Domain], AF_INET4
jnz .no_tcp jnz .no_tcp
@ -1352,7 +1417,7 @@ SOCKET_free:
mov ebx, [eax + SOCKET.NextPtr] mov ebx, [eax + SOCKET.NextPtr]
mov eax, [eax + SOCKET.PrevPtr] mov eax, [eax + SOCKET.PrevPtr]
DEBUGF 1, "linking socket %x to socket %x\n", eax, ebx DEBUGF 1, "SOCKET_free: linking socket %x to socket %x\n", eax, ebx
test eax, eax test eax, eax
jz @f jz @f
@ -1367,7 +1432,7 @@ SOCKET_free:
call kernel_free call kernel_free
pop ebx pop ebx
DEBUGF 1, "socket is gone!\n" DEBUGF 1, "SOCKET_free: success!\n"
.error: .error:
ret ret