Subversion Repositories Kolibri OS

Compare Revisions

Regard whitespace Rev 1195 → Rev 1196

/kernel/branches/net/applications/netcfg/netcfg.asm
38,8 → 38,8
jne @f
mcall -1 ; close this program
@@:
cmp eax,0x0000fe00
jg @f
cmp eax,0x0000ff00
jg load_drv
 
cmp ah, 4
je hook
51,19 → 51,11
je unload
 
jmp still
@@:
shr eax, 16
mov word [selected], ax
 
call load_drv
call draw_window
 
jmp still
 
load_drv:
; mov ax , [selected]
test ax , ax
jz still
shr eax, 16
mov word [selected], ax
 
mov bl , 6 ; get a dword
mov bh , ah ; bus
81,8 → 73,16
 
mov [IOCTL.handle], eax
 
ret
call draw_window
 
cmp [IOCTL.handle], 0
jne still
 
mcall 4, 20 shl 16 + 30, 1 shl 31 + 0x00ff0000 , load_error
 
jmp still
 
 
hook:
mov ax , [selected]
test ax , ax
101,26 → 101,24
 
mov byte[drivernumber], al
 
jmp still
 
reset:
movzx ebx, byte[drivernumber]
mcall 73,,2
 
ret
jmp still
 
unload:
movzx ebx, byte[drivernumber]
mcall 73,,3
 
ret
jmp still
 
draw_window:
mcall 12, 1 ; start of draw
mcall 0, dword [Form], dword [Form + 4], 0x13ffffff, 0x805080d0, title
 
; mcall 73, 1,
; mov ecx, eax
; mcall 47, 1 shl 18, , 50 shl 16 + 10, 0x00000000
 
call Get_PCI_Info ; get pci version and last bus, scan for and draw each pci device
 
cmp edx, 20 shl 16 + 110
128,9 → 126,10
 
mcall 4, 20 shl 16 + 100, 1 shl 31 + 0x00000000 , caption
 
mov ax , [selected]
test ax, ax
cmp [selected], 0
jz .done
cmp [IOCTL.handle] ,0
jz .done
 
mcall 8, 18 shl 16 + 100, 35 shl 16 + 18, 4, 0x00007f00
mcall ,, 55 shl 16 + 18, 5, 0x0000007f
379,8 → 378,8
driverfound:
ret
 
include 'VENDORS.INC'
include 'DRIVERS.INC'
include 'vendors.inc'
include 'drivers.inc'
;------------------------------------------------------------------
; DATA AREA
DATA
404,6 → 403,7
lbl_none db 'none',0
;lbl_unknown db 'unknown',0
;lbl_ethernet db 'ethernet',0
load_error db 'Could not load driver!',0
 
devicename db 'test'
rb 64
/kernel/branches/net/applications/zeroconf/zeroconf.asm
42,14 → 42,11
DEFEND_INTERVAL equ 10 ; seconds (min. wait between defensive ARPs)
 
 
 
 
AF_INET4 equ 2 ;;;;;
IP_PROTO_UDP equ 17
 
 
 
 
include '../proc32.inc'
include '../macros.inc'
include '../debug-fdo.inc'
197,22 → 194,22
invoke ini.get_str, path, str_ipconfig, str_ip, inibuf, 16, 0
mov edx, inibuf
call Ip2dword
mcall 73, 3, edx
mcall 75, 3, edx
 
invoke ini.get_str, path, str_ipconfig, str_gateway, inibuf, 16, 0
mov edx, inibuf
call Ip2dword
mcall 73, 9, edx
mcall 75, 9, edx
 
invoke ini.get_str, path, str_ipconfig, str_dns, inibuf, 16, 0
mov edx, inibuf
call Ip2dword
mcall 73, 7, edx
mcall 75, 7, edx
 
invoke ini.get_str, path, str_ipconfig, str_subnet, inibuf, 16, 0
mov edx, inibuf
call Ip2dword
mcall 73, 5, edx
mcall 75, 5, edx
 
 
mcall -1
478,11 → 475,11
call random
mov ecx,0xfea9 ; IP 169.254.0.0 link local net, see RFC3927
mov cx,ax
mcall 73, 3, ecx ; mask is 255.255.0.0
mcall 75, 3, ecx ; mask is 255.255.0.0
DEBUGF 1,"Link Local IP assinged: 169.254.%u.%u\n",[generator+2]:1,[generator+3]:1
mcall 73, 5, 0xffff
mcall 73, 9, 0x0
mcall 73, 7, 0x0
mcall 75, 5, 0xffff
mcall 75, 9, 0x0
mcall 75, 7, 0x0
 
mcall 5, PROBE_WAIT*100
 
559,7 → 556,7
libini,'libini.obj'
 
import libini, \
ini.get_str,'ini.get_str'
ini.get_str,'ini_get_str'
 
include_debug_strings
 
575,7 → 572,7
sockaddr1:
 
dw AF_INET4
dw 68 ; local port
dw 68 shl 8 ; local port
dd 0 ; local IP
 
rb 10
584,7 → 581,7
sockaddr2:
 
dw AF_INET4
dw 67 ; destination port
dw 67 shl 8 ; destination port
dd -1 ; destination IP
 
rb 10
/kernel/branches/net/drivers/pcnet32.asm
0,0 → 1,1637
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;; GNU GENERAL PUBLIC LICENSE ;;
;; Version 2, June 1991 ;;
;; ;;
;; Status: under construction ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
;$Revision$
 
format MS COFF
 
API_VERSION equ 0x01000100
 
DEBUG equ 1
__DEBUG__ equ 1
__DEBUG_LEVEL__ equ 1
 
MAX_PCNET equ 4
MAX_ETH_FRAME_SIZE equ 1514
 
include 'proc32.inc'
include 'imports.inc'
include 'fdo.inc'
 
OS_BASE equ 0;
new_app_base equ 0x60400000
PROC_BASE equ OS_BASE+0x0080000
 
public START
public service_proc
public version
 
struc IOCTL {
.handle dd ?
.io_code dd ?
.input dd ?
.inp_size dd ?
.output dd ?
.out_size dd ?
}
 
virtual at 0
IOCTL IOCTL
end virtual
 
struc ETH_DEVICE {
; pointers to procedures
.unload dd ?
.reset dd ?
.transmit dd ?
.set_MAC dd ?
.get_MAC dd ?
.set_mode dd ?
.get_mode dd ?
; status
.bytes_tx dq ?
.bytes_rx dq ?
.packets_tx dd ?
.packets_rx dd ?
.mode dd ? ; This dword contains cable status (10mbit/100mbit, full/half duplex, auto negotiation or not,..)
.name dd ?
.mac dp ?
; device specific
 
.rx_buffer dd ?
.tx_buffer dd ?
 
.io_addr dd ?
.irq_line db ?
.pci_bus db ?
.pci_dev db ?
 
.private:
.mode_ dw ?
.tlen_rlen dw ?
.reserved dw ?
.filter dq ?
.rx_ring dd ?
.tx_ring dd ?
.cur_rx db ?
.cur_tx db ?
.dirty_rx dd ?
.dirty_tx dd ?
.tx_full db ?
.options dd ?
.full_duplex db ?
.chip_version dd ?
.mii db ?
.ltint db ?
.dxsuflo db ?
.fset db ?
.fdx db ?
 
.access_read_csr dd ?
.access_write_csr dd ?
.access_read_bcr dd ?
.access_write_bcr dd ?
.access_read_rap dd ?
.access_write_rap dd ?
.access_reset dd ?
 
.size:
 
}
 
virtual at 0
device ETH_DEVICE
end virtual
 
struc buf_head {
.base dd ?
.length dw ?
.status dw ?
.misc dd ?
.reserved dd ?
 
.size:
}
 
virtual at 0
buf_head buf_head
end virtual
 
struc rx_desc_2 { ; Swstyle 2
 
.rbadr dd ?
.status dd ?
.rfrtag dd ?
 
; +--------+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+
; |Address | 31 | 30 | 29 | 28 | 27 | 26 | 25 | 24 | 23 | 22 | 21 | 20 |19-16|15-12|11-0 |
; +--------+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+
; |CRDA+00h| RBADR[31:0] |
; +--------+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+
; |CRDA+04h| OWN | ERR |FRAM |OFLO | CRC |BUFF | STP | ENP | BPE | PAM |LAFM | BAM | RES |1111 |BCNT |
; +--------+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+
; |CRDA+08h| RES | RFRTAG[14:0] |0000 |MCNT |
; +--------+-----+-----------------------------------------------------------------------+-----+-----+
; |CRDA+0Ch| USER SPACE | | |
; +--------+-----------------------------------------------------------------------------+-----+-----+
 
}
 
struc rx_desc_3 { ; Swstyle 3
 
.mcnt dd ?
.status dd ?
.rbadr dd ?
 
; +--------+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+
; |Address | 31 | 30 | 29 | 28 | 27 | 26 | 25 | 24 | 23 |22-16|15-12|11-0 |
; +--------+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+
; |CRDA+00h| RES | RES | RES |0000 |MCNT |
; +--------+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+
; |CRDA+04h| OWN | ERR |FRAM |OFLO | CRC |BUFF | STP | ENP | BPE | RES |1111 |BCNT |
; +--------+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+
; |CRDA+08h| RBADR[31:0] |
; +--------+-----------------------------------------------------------------------+
; |CRDA+0Ch| USER SPACE |
; +--------+-----------------------------------------------------------------------+
 
}
 
virtual at 0
rx_desc rx_desc_2
end virtual
 
 
; PCI Bus defines
 
PCI_HEADER_TYPE equ 0x0e ;8 bit
PCI_BASE_ADDRESS_0 equ 0x10 ;32 bit
PCI_BASE_ADDRESS_5 equ 0x24 ;32 bits
PCI_BASE_ADDRESS_SPACE_IO equ 0x01
PCI_VENDOR_ID equ 0x00 ;16 bit
PCI_BASE_ADDRESS_IO_MASK equ 0xFFFFFFFC
 
PCNET_PORT_AUI equ 0x00
PCNET_PORT_10BT equ 0x01
PCNET_PORT_GPSI equ 0x02
PCNET_PORT_MII equ 0x03
PCNET_PORT_PORTSEL equ 0x03
PCNET_PORT_ASEL equ 0x04
PCNET_PORT_100 equ 0x40
PCNET_PORT_FD equ 0x80
 
PCNET_DMA_MASK equ 0xffffffff
 
PCNET_LOG_TX_BUFFERS equ 1
PCNET_LOG_RX_BUFFERS equ 2
 
PCNET_TX_RING_SIZE equ 4
PCNET_TX_RING_MOD_MASK equ (PCNET_TX_RING_SIZE-1)
PCNET_TX_RING_LEN_BITS equ 0
 
PCNET_RX_RING_SIZE equ 4
PCNET_RX_RING_MOD_MASK equ (PCNET_RX_RING_SIZE-1)
PCNET_RX_RING_LEN_BITS equ (PCNET_LOG_RX_BUFFERS shl 4)
 
PCNET_PKT_BUF_SZ equ 1544
PCNET_PKT_BUF_SZ_NEG equ 0xf9f8
 
PCNET_WIO_RDP equ 0x10
PCNET_WIO_RAP equ 0x12
PCNET_WIO_RESET equ 0x14
PCNET_WIO_BDP equ 0x16
PCNET_DWIO_RDP equ 0x10
PCNET_DWIO_RAP equ 0x14
PCNET_DWIO_RESET equ 0x18
PCNET_DWIO_BDP equ 0x1C
PCNET_TOTAL_SIZE equ 0x20
 
; CSR registers
 
PCNET_CSR_CSR equ 0x00
PCNET_CSR_IAB0 equ 0x01
PCNET_CSR_IAB1 equ 0x02
PCNET_CSR_IMR equ 0x03
PCNET_CSR_TFEAT equ 0x04
PCNET_CSR_EXTCTL1 equ 0x05
PCNET_CSR_DTBLLEN equ 0x06
PCNET_CSR_EXTCTL2 equ 0x07
PCNET_CSR_MAR0 equ 0x08
PCNET_CSR_MAR1 equ 0x09
PCNET_CSR_MAR2 equ 0x0A
PCNET_CSR_MAR3 equ 0x0B
PCNET_CSR_PAR0 equ 0x0C
PCNET_CSR_PAR1 equ 0x0D
PCNET_CSR_PAR2 equ 0x0E
PCNET_CSR_MODE equ 0x0F
PCNET_CSR_RXADDR0 equ 0x18
PCNET_CSR_RXADDR1 equ 0x19
PCNET_CSR_TXADDR0 equ 0x1E
PCNET_CSR_TXADDR1 equ 0x1F
PCNET_CSR_TXPOLL equ 0x2F
PCNET_CSR_RXPOLL equ 0x31
PCNET_CSR_RXRINGLEN equ 0x4C
PCNET_CSR_TXRINGLEN equ 0x4E
PCNET_CSR_DMACTL equ 0x50
PCNET_CSR_BUSTIMER equ 0x52
PCNET_CSR_MEMERRTIMEO equ 0x64
PCNET_CSR_ONNOWMISC equ 0x74
PCNET_CSR_ADVFEAT equ 0x7A
PCNET_CSR_MACCFG equ 0x7D
PCNET_CSR_CHIPID0 equ 0x58
PCNET_CSR_CHIPID1 equ 0x59
 
; Control and Status Register (CSR0)
 
PCNET_CSR_INIT equ 1 shl 0
PCNET_CSR_START equ 1 shl 1
PCNET_CSR_STOP equ 1 shl 2
PCNET_CSR_TX equ 1 shl 3
PCNET_CSR_TXON equ 1 shl 4
PCNET_CSR_RXON equ 1 shl 5
PCNET_CSR_INTEN equ 1 shl 6
PCNET_CSR_INTR equ 1 shl 7
PCNET_CSR_IDONE equ 1 shl 8
PCNET_CSR_TINT equ 1 shl 9
PCNET_CSR_RINT equ 1 shl 10
PCNET_CSR_MERR equ 1 shl 11
PCNET_CSR_MISS equ 1 shl 12
PCNET_CSR_CERR equ 1 shl 13
 
; Interrupt masks and deferral control (CSR3)
 
PCNET_IMR_BSWAP equ 0x0004
PCNET_IMR_ENMBA equ 0x0008 ; enable modified backoff alg
PCNET_IMR_DXMT2PD equ 0x0010
PCNET_IMR_LAPPEN equ 0x0020 ; lookahead packet processing enb
PCNET_IMR_DXSUFLO equ 0x0040 ; disable TX stop on underflow
PCNET_IMR_IDONE equ 0x0100
PCNET_IMR_TINT equ 0x0200
PCNET_IMR_RINT equ 0x0400
PCNET_IMR_MERR equ 0x0800
PCNET_IMR_MISS equ 0x1000
 
PCNET_IMR equ PCNET_IMR_TINT+PCNET_IMR_RINT+PCNET_IMR_IDONE+PCNET_IMR_MERR+PCNET_IMR_MISS
 
; Test and features control (CSR4)
 
PCNET_TFEAT_TXSTRTMASK equ 0x0004
PCNET_TFEAT_TXSTRT equ 0x0008
PCNET_TFEAT_RXCCOFLOWM equ 0x0010 ; Rx collision counter oflow
PCNET_TFEAT_RXCCOFLOW equ 0x0020
PCNET_TFEAT_UINT equ 0x0040
PCNET_TFEAT_UINTREQ equ 0x0080
PCNET_TFEAT_MISSOFLOWM equ 0x0100
PCNET_TFEAT_MISSOFLOW equ 0x0200
PCNET_TFEAT_STRIP_FCS equ 0x0400
PCNET_TFEAT_PAD_TX equ 0x0800
PCNET_TFEAT_TXDPOLL equ 0x1000
PCNET_TFEAT_DMAPLUS equ 0x4000
 
; Extended control and interrupt 1 (CSR5)
 
PCNET_EXTCTL1_SPND equ 0x0001 ; suspend
PCNET_EXTCTL1_MPMODE equ 0x0002 ; magic packet mode
PCNET_EXTCTL1_MPENB equ 0x0004 ; magic packet enable
PCNET_EXTCTL1_MPINTEN equ 0x0008 ; magic packet interrupt enable
PCNET_EXTCTL1_MPINT equ 0x0010 ; magic packet interrupt
PCNET_EXTCTL1_MPPLBA equ 0x0020 ; magic packet phys. logical bcast
PCNET_EXTCTL1_EXDEFEN equ 0x0040 ; excessive deferral interrupt enb.
PCNET_EXTCTL1_EXDEF equ 0x0080 ; excessive deferral interrupt
PCNET_EXTCTL1_SINTEN equ 0x0400 ; system interrupt enable
PCNET_EXTCTL1_SINT equ 0x0800 ; system interrupt
PCNET_EXTCTL1_LTINTEN equ 0x4000 ; last TX interrupt enb
PCNET_EXTCTL1_TXOKINTD equ 0x8000 ; TX OK interrupt disable
 
; RX/TX descriptor len (CSR6)
 
PCNET_DTBLLEN_RLEN equ 0x0F00
PCNET_DTBLLEN_TLEN equ 0xF000
 
; Extended control and interrupt 2 (CSR7)
 
PCNET_EXTCTL2_MIIPDTINTE equ 0x0001
PCNET_EXTCTL2_MIIPDTINT equ 0x0002
PCNET_EXTCTL2_MCCIINTE equ 0x0004
PCNET_EXTCTL2_MCCIINT equ 0x0008
PCNET_EXTCTL2_MCCINTE equ 0x0010
PCNET_EXTCTL2_MCCINT equ 0x0020
PCNET_EXTCTL2_MAPINTE equ 0x0040
PCNET_EXTCTL2_MAPINT equ 0x0080
PCNET_EXTCTL2_MREINTE equ 0x0100
PCNET_EXTCTL2_MREINT equ 0x0200
PCNET_EXTCTL2_STINTE equ 0x0400
PCNET_EXTCTL2_STINT equ 0x0800
PCNET_EXTCTL2_RXDPOLL equ 0x1000
PCNET_EXTCTL2_RDMD equ 0x2000
PCNET_EXTCTL2_RXFRTG equ 0x4000
PCNET_EXTCTL2_FASTSPNDE equ 0x8000
 
; Mode (CSR15)
 
PCNET_MODE_RXD equ 0x0001 ; RX disable
PCNET_MODE_TXD equ 0x0002 ; TX disable
PCNET_MODE_LOOP equ 0x0004 ; loopback enable
PCNET_MODE_TXCRCD equ 0x0008
PCNET_MODE_FORCECOLL equ 0x0010
PCNET_MODE_RETRYD equ 0x0020
PCNET_MODE_INTLOOP equ 0x0040
PCNET_MODE_PORTSEL equ 0x0180
PCNET_MODE_RXVPAD equ 0x2000
PCNET_MODE_RXNOBROAD equ 0x4000
PCNET_MODE_PROMISC equ 0x8000
 
; BCR (Bus Control Registers)
 
PCNET_BCR_MMRA equ 0x00 ; Master Mode Read Active
PCNET_BCR_MMW equ 0x01 ; Master Mode Write Active
PCNET_BCR_MISCCFG equ 0x02
PCNET_BCR_LED0 equ 0x04
PCNET_BCR_LED1 equ 0x05
PCNET_BCR_LED2 equ 0x06
PCNET_BCR_LED3 equ 0x07
PCNET_BCR_DUPLEX equ 0x09
PCNET_BCR_BUSCTL equ 0x12
PCNET_BCR_EECTL equ 0x13
PCNET_BCR_SSTYLE equ 0x14
PCNET_BCR_PCILAT equ 0x16
PCNET_BCR_PCISUBVENID equ 0x17
PCNET_BCR_PCISUBSYSID equ 0x18
PCNET_BCR_SRAMSIZE equ 0x19
PCNET_BCR_SRAMBOUND equ 0x1A
PCNET_BCR_SRAMCTL equ 0x1B
PCNET_BCR_MIICTL equ 0x20
PCNET_BCR_MIIADDR equ 0x21
PCNET_BCR_MIIDATA equ 0x22
PCNET_BCR_PCIVENID equ 0x23
PCNET_BCR_PCIPCAP equ 0x24
PCNET_BCR_DATA0 equ 0x25
PCNET_BCR_DATA1 equ 0x26
PCNET_BCR_DATA2 equ 0x27
PCNET_BCR_DATA3 equ 0x28
PCNET_BCR_DATA4 equ 0x29
PCNET_BCR_DATA5 equ 0x2A
PCNET_BCR_DATA6 equ 0x2B
PCNET_BCR_DATA7 equ 0x2C
PCNET_BCR_ONNOWPAT0 equ 0x2D
PCNET_BCR_ONNOWPAT1 equ 0x2E
PCNET_BCR_ONNOWPAT2 equ 0x2F
PCNET_BCR_PHYSEL equ 0x31
 
; RX status register
 
PCNET_RXSTAT_BPE equ 0x0080 ; bus parity error
PCNET_RXSTAT_ENP equ 0x0100 ; end of packet
PCNET_RXSTAT_STP equ 0x0200 ; start of packet
PCNET_RXSTAT_BUFF equ 0x0400 ; buffer error
PCNET_RXSTAT_CRC equ 0x0800 ; CRC error
PCNET_RXSTAT_OFLOW equ 0x1000 ; rx overrun
PCNET_RXSTAT_FRAM equ 0x2000 ; framing error
PCNET_RXSTAT_ERR equ 0x4000 ; error summary
PCNET_RXSTAT_OWN equ 0x8000
 
; TX status register
 
PCNET_TXSTAT_TRC equ 0x0000000F ; transmit retries
PCNET_TXSTAT_RTRY equ 0x04000000 ; retry
PCNET_TXSTAT_LCAR equ 0x08000000 ; lost carrier
PCNET_TXSTAT_LCOL equ 0x10000000 ; late collision
PCNET_TXSTAT_EXDEF equ 0x20000000 ; excessive deferrals
PCNET_TXSTAT_UFLOW equ 0x40000000 ; transmit underrun
PCNET_TXSTAT_BUFF equ 0x80000000 ; buffer error
 
PCNET_TXCTL_OWN equ 0x80000000
PCNET_TXCTL_ERR equ 0x40000000 ; error summary
PCNET_TXCTL_ADD_FCS equ 0x20000000 ; add FCS to pkt
PCNET_TXCTL_MORE_LTINT equ 0x10000000
PCNET_TXCTL_ONE equ 0x08000000
PCNET_TXCTL_DEF equ 0x04000000
PCNET_TXCTL_STP equ 0x02000000
PCNET_TXCTL_ENP equ 0x01000000
PCNET_TXCTL_BPE equ 0x00800000
PCNET_TXCTL_MBO equ 0x0000F000
PCNET_TXCTL_BUFSZ equ 0x00000FFF
 
 
 
 
section '.flat' code readable align 16
 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; proc START ;;
;; ;;
;; (standard driver proc) ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
proc START stdcall, state:dword
 
cmp [state], 1
jne .exit
 
.entry:
 
DEBUGF 1,"Loading PCnet driver\n"
stdcall RegService, my_service, service_proc
ret
 
.fail:
.exit:
xor eax, eax
ret
 
endp
 
 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; proc SERVICE_PROC ;;
;; ;;
;; (standard driver proc) ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
align 4
proc service_proc stdcall, ioctl:dword
 
mov edx, [ioctl]
mov eax, [ebx+IOCTL.io_code]
 
;------------------------------------------------------
 
cmp eax, 0 ;SRV_GETVERSION
jne @F
 
cmp [edx+IOCTL.out_size], 4
jl .fail
mov eax, [edx+IOCTL.output]
mov [eax], dword API_VERSION
 
xor eax, eax
ret
 
;------------------------------------------------------
@@:
cmp eax, 1 ;SRV_HOOK
jne .fail
 
mov eax, [esp]
 
cmp [edx + IOCTL.inp_size], 3 ; Data input must be at least 3 bytes
jl .fail
 
mov eax, [edx + IOCTL.input]
cmp byte [eax], 1 ; 1 means device number and bus number (pci) are given
jne .fail ; other types arent supported for this card yet
 
; check if the device is already listed
 
mov esi, PCNET_LIST
mov ecx, [PCNET_DEV]
test ecx, ecx
jz .firstdevice
mov eax, [edx+IOCTL.input] ; get the pci bus and device numbers
mov bx , [eax+1] ;
.nextdevice:
lodsd
cmp bx , word [eax + device.pci_bus] ; compare with pci and device num in RTL8139 list (notice the usage of word instead of byte)
je .find_devicenum ; Device is already loaded, let's find it's device number
 
loop .nextdevice
 
; This device doesnt have its own eth_device structure yet, lets create one
 
.firstdevice:
cmp [PCNET_DEV], MAX_PCNET ; First check if the driver can handle one more card
jge .fail
 
push edx
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
 
mov dword [ebx+device.reset], reset
mov dword [ebx+device.transmit], transmit
mov dword [ebx+device.get_MAC], read_mac
mov dword [ebx+device.set_MAC], write_mac
mov dword [ebx+device.unload], unload
mov dword [ebx+device.name], my_service
 
; save the pci bus and device numbers
 
mov eax, [edx+IOCTL.input]
mov cl , [eax+1]
mov [ebx+device.pci_bus], cl
mov cl , [eax+2]
mov [ebx+device.pci_dev], cl
 
; Now, it's time to find the base io addres of the PCI device
; TODO: implement check if bus and dev exist on this machine
 
mov edx, PCI_BASE_ADDRESS_0
.reg_check:
movzx eax, byte [ebx+device.pci_bus]
movzx ecx, byte [ebx+device.pci_dev]
 
push edx ecx
stdcall PciRead16, eax ,ecx ,edx
pop ecx edx
 
mov [ebx+device.io_addr], eax
and eax, PCI_BASE_ADDRESS_IO_MASK
test eax, eax
jz .inc_reg
mov eax, [ebx+device.io_addr]
and eax, PCI_BASE_ADDRESS_SPACE_IO
test eax, eax
jz .inc_reg
 
mov eax, [ebx+device.io_addr]
and eax, PCI_BASE_ADDRESS_IO_MASK
mov [ebx+device.io_addr], eax
jmp .got_io
 
.inc_reg:
add edx, 4
cmp edx, PCI_BASE_ADDRESS_5
jbe .reg_check
 
.got_io:
 
; We've found the io address, find IRQ now
 
movzx eax, byte [ebx+device.pci_bus]
movzx ecx, byte [ebx+device.pci_dev]
push ebx
stdcall PciRead8, eax ,ecx ,0x3c ; 0x3c is the offset where irq can be found
pop ebx
mov byte [ebx+device.irq_line], al
 
DEBUGF 1,"Hooking into device, dev:%x, bus:%x, irq:%x, addr:%x\n",\
[ebx+device.pci_dev]:1,[ebx+device.pci_bus]:1,[ebx+device.irq_line]:1,[ebx+device.io_addr]:4
 
 
; Allocate the Receive buffer
 
stdcall KernelAlloc, PCNET_RX_RING_SIZE * PCNET_PKT_BUF_SZ
test eax, eax
jz .err
mov [ebx+device.rx_buffer], eax ; Save the address to it into the device struct
 
; Allocate the Transmit Buffer
 
stdcall KernelAlloc, PCNET_TX_RING_SIZE * PCNET_PKT_BUF_SZ
test eax, eax
jz .err
mov [ebx+device.tx_buffer], eax
 
; Allocate the RX Ring
 
stdcall KernelAlloc, PCNET_RX_RING_SIZE * buf_head.size
test eax, eax
jz .err
mov dword [ebx + device.rx_ring], eax
 
; Allocate the TX ring
 
stdcall KernelAlloc, PCNET_TX_RING_SIZE * buf_head.size
test eax, eax
jz .err
mov dword [ebx + device.tx_ring], eax
 
; fill in some of the structure variables
 
call switch_to_wio
 
mov edi, [ebx + device.rx_ring]
mov ecx, PCNET_RX_RING_SIZE
mov eax, [ebx + device.rx_buffer]
call GetPgAddr
.rx_init:
mov [edi + buf_head.base], eax
mov [edi + buf_head.length], PCNET_PKT_BUF_SZ_NEG
mov [edi + buf_head.status], 0x8000
add eax, PCNET_PKT_BUF_SZ
; inc eax
add edi, buf_head.size
loop .rx_init
 
mov edi, [ebx + device.tx_ring]
mov ecx, PCNET_TX_RING_SIZE
.tx_init:
mov [edi + buf_head.base], 0
mov [edi + buf_head.status], 0
add edi, buf_head.size
loop .tx_init
 
mov [ebx + device.tlen_rlen],(PCNET_TX_RING_LEN_BITS or PCNET_RX_RING_LEN_BITS)
 
; Ok, the eth_device structure is ready, let's probe the device
 
call probe ; this function will output in eax
test eax, eax
jnz .err ; If an error occured, exit
 
mov eax, [PCNET_DEV] ; Add the device structure to our device list
mov [PCNET_LIST+4*eax], ebx ; (IRQ handler uses this list to find device)
inc [PCNET_DEV] ;
 
call EthRegDev
cmp eax, -1
je .destroy
 
ret
 
; If the device was already loaded, find the device number and return it in eax
 
.find_devicenum:
DEBUGF 1,"Trying to find device number of already registered device\n"
mov ebx, eax
call EthStruc2Dev ; This kernel procedure converts a pointer to device struct in ebx
; into a device number in edi
mov eax, edi ; Application wants it in eax instead
DEBUGF 1,"Kernel says: %u\n", eax
ret
 
; If an error occured, remove all allocated data and exit (returning -1 in eax)
 
.destroy:
; todo: reset device into virgin state
 
.err:
DEBUGF 1,"Error, removing all data !\n"
stdcall KernelFree, dword [ebx+device.rx_buffer]
stdcall KernelFree, dword [ebx+device.tx_buffer]
stdcall KernelFree, ebx
 
.fail:
or eax, -1
ret
 
;------------------------------------------------------
endp
 
 
;;/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\;;
;; ;;
;; Actual Hardware dependent code starts here ;;
;; ;;
;;/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\;;
 
align 4
unload:
; TODO: (in this particular order)
;
; - Stop the device
; - Detach int handler
; - Remove device from local list (RTL8139_LIST)
; - call unregister function in kernel
; - Remove all allocated structures and buffers the card used
 
or eax,-1
 
ret
 
 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; probe: enables the device (if it really is a PCnet device)
;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
align 4
probe:
mov edx, [ebx + device.io_addr]
 
call wio_reset
 
xor ecx, ecx
call wio_read_csr
cmp eax, 4
jne .try_dwio
 
; Try Word I/O
mov ax , 88
add edx, PCNET_WIO_RAP
out dx , ax
nop
nop
in ax , dx
sub edx, PCNET_WIO_RAP
cmp ax , 88
jne .try_dwio
 
DEBUGF 1,"Using WIO\n"
 
call switch_to_wio
 
jmp .L1
 
.try_dwio:
call dwio_reset
 
xor ecx, ecx
call dwio_read_csr
cmp eax, 4
jne .no_dev
 
; Try Dword I/O
add edx, PCNET_DWIO_RAP
mov eax, 88
out dx , eax
nop
nop
in eax, dx
sub edx, PCNET_DWIO_RAP
and eax, 0xffff
cmp eax, 88
jne .no_dev
 
DEBUGF 1,"Using DWIO\n"
 
call switch_to_dwio
 
jmp .L1
 
.no_dev:
DEBUGF 1,"PCnet device not found!\n"
mov eax, 1
ret
.L1:
; TODO: remember to use WORD or DWORD operations
 
;;; stdcall Sleep, 10
 
;---------------------------------------------
; Switch to dword operations
 
; DEBUGF 1,"Switching to 32\n"
;
; mov ecx, PCNET_DWIO_RDP
; mov eax, 0
; call wio_write_csr
 
;---------------------------------------------
 
mov ecx, PCNET_CSR_CHIPID0
call [ebx + device.access_read_csr]
mov esi, eax
 
mov ecx, PCNET_CSR_CHIPID1
call [ebx + device.access_read_csr]
shl eax, 16
or eax, esi
 
mov ecx, eax
and ecx, 0xfff
cmp ecx, 3
jne .no_dev
 
shr eax, 12
and eax, 0xffff
mov [ebx + device.chip_version], eax
 
DEBUGF 1,"chip version ok\n"
mov [ebx + device.fdx], 0
mov [ebx + device.mii], 0
mov [ebx + device.fset], 0
mov [ebx + device.dxsuflo], 0
mov [ebx + device.ltint], 0
 
cmp eax, 0x2420
je .L2
cmp eax, 0x2430
je .L2
 
mov [ebx + device.fdx], 1
 
cmp eax, 0x2621
je .L4
cmp eax, 0x2623
je .L5
cmp eax, 0x2624
je .L6
cmp eax, 0x2625
je .L7
cmp eax, 0x2626
je .L8
cmp eax, 0x2627
je .L9
 
DEBUGF 1,"Invalid chip rev\n"
jmp .no_dev
.L2:
mov [ebx + device.name], device_l2
jmp .L10
.L4:
mov [ebx + device.name], device_l4
; mov [ebx + device.fdx], 1
jmp .L10
.L5:
mov [ebx + device.name], device_l5
; mov [ebx + device.fdx], 1
mov [ebx + device.mii], 1
mov [ebx + device.fset], 1
mov [ebx + device.ltint], 1
jmp .L10
.L6:
mov [ebx + device.name], device_l6
; mov [ebx + device.fdx], 1
mov [ebx + device.mii], 1
mov [ebx + device.fset], 1
jmp .L10
.L7:
mov [ebx + device.name], device_l7
; mov [ebx + device.fdx], 1
mov [ebx + device.mii], 1
jmp .L10
.L8:
mov [ebx + device.name], device_l8
; mov [ebx + device.fdx], 1
mov ecx, PCNET_CSR_RXPOLL
call dword [ebx + device.access_read_bcr]
call dword [ebx + device.access_write_bcr]
jmp .L10
.L9:
mov [ebx + device.name], device_l9
; mov [ebx + device.fdx], 1
mov [ebx + device.mii], 1
.L10:
DEBUGF 1,"device name: %s\n",[ebx + device.name]
 
cmp [ebx + device.fset], 1
jne .L11
mov ecx, PCNET_BCR_BUSCTL
call [ebx + device.access_read_bcr]
or eax, 0x800
call [ebx + device.access_write_bcr]
 
mov ecx, PCNET_CSR_DMACTL
call [ebx + device.access_read_csr]
; and eax, 0xc00
; or eax, 0xc00
mov eax, 0xc00
call [ebx + device.access_write_csr]
 
mov [ebx + device.dxsuflo],1
mov [ebx + device.ltint],1
.L11:
 
push ebx
call adjust_pci_device
pop ebx
 
DEBUGF 1,"PCI done\n"
mov eax, PCNET_PORT_ASEL
mov [ebx + device.options], eax
mov [ebx + device.mode_], word 0x0003
mov [ebx + device.tlen_rlen], word (PCNET_TX_RING_LEN_BITS or PCNET_RX_RING_LEN_BITS)
 
mov dword [ebx + device.filter], 0
mov dword [ebx + device.filter+4], 0
 
mov eax, PCNET_IMR
mov ecx, PCNET_CSR_IMR ; Write interrupt mask
call [ebx + device.access_write_csr]
 
if 0
 
mov ecx, PCNET_BCR_SSTYLE ; Select Software style 2 TODO: freebsd driver uses style 3, why?
mov eax, 2
call [ebx + device.access_write_bcr]
 
 
; ------------ really nescessary??? ----------------
lea eax, [ebx + device.private]
mov ecx, eax
and ecx, 0xFFF ; KolibriOS PAGE SIZE
call GetPgAddr
add eax, ecx
 
and eax, 0xffff
mov ecx, PCNET_CSR_IAB0
call [ebx + device.access_write_csr]
 
 
lea eax, [ebx + device.private]
mov ecx, eax
and ecx, 0xFFF ; KolibriOS PAGE SIZE
call GetPgAddr
add eax, ecx
 
shr eax,16
mov ecx, PCNET_CSR_IAB1
call [ebx + device.access_write_csr]
 
mov ecx, PCNET_CSR_CSR
mov eax, 1
call [ebx + device.access_write_csr]
; ------------------------------------------------
end if
 
stdcall Sleep, 1
 
 
reset:
 
; attach int handler
 
movzx eax, [ebx+device.irq_line]
DEBUGF 1,"Attaching int handler to irq %x\n",eax:1
stdcall AttachIntHandler, eax, int_handler, dword 0
test eax, eax
jnz @f
DEBUGF 1,"\nCould not attach int handler!\n"
; or eax, -1
; ret
@@:
 
mov edx, [ebx + device.io_addr]
call [ebx + device.access_reset]
 
; Switch pcnet32 to 32bit mode
mov ecx, PCNET_BCR_SSTYLE
mov eax, 2
call [ebx + device.access_write_bcr]
 
; set/reset autoselect bit
mov ecx, PCNET_BCR_MISCCFG
call [ebx + device.access_read_bcr]
and eax,not 2
test [ebx + device.options], PCNET_PORT_ASEL
jz .L1
or eax, 2
.L1:
call [ebx + device.access_write_bcr]
 
 
; Handle full duplex setting
cmp byte [ebx + device.full_duplex], 0
je .L2
mov ecx, PCNET_BCR_DUPLEX
call [ebx + device.access_read_bcr]
and eax, not 3
test [ebx + device.options], PCNET_PORT_FD
jz .L3
or eax, 1
cmp [ebx + device.options], PCNET_PORT_FD or PCNET_PORT_AUI
jne .L4
or eax, 2
jmp .L4
.L3:
test [ebx + device.options], PCNET_PORT_ASEL
jz .L4
cmp [ebx + device.chip_version], 0x2627
jne .L4
or eax, 3
.L4:
mov ecx, PCNET_BCR_DUPLEX
call [ebx + device.access_write_bcr]
.L2:
 
 
; set/reset GPSI bit in test register
mov ecx, 124
call [ebx + device.access_read_csr]
mov ecx, [ebx + device.options]
and ecx, PCNET_PORT_PORTSEL
cmp ecx, PCNET_PORT_GPSI
jne .L5
or eax, 0x10
.L5:
call [ebx + device.access_write_csr]
cmp [ebx + device.mii], 0
je .L6
test [ebx + device.options], PCNET_PORT_ASEL
jnz .L6
mov ecx, PCNET_BCR_MIICTL
call [ebx + device.access_read_bcr]
and eax,not 0x38
test [ebx + device.options], PCNET_PORT_FD
jz .L7
or eax, 0x10
.L7:
test [ebx + device.options], PCNET_PORT_100
jz .L8
or eax, 0x08
.L8:
call [ebx + device.access_write_bcr]
jmp .L9
.L6:
test [ebx + device.options], PCNET_PORT_ASEL
jz .L9
mov ecx, PCNET_BCR_MIICTL
DEBUGF 1,"ASEL, enable auto-negotiation\n"
call [ebx + device.access_read_bcr]
and eax, not 0x98
or eax, 0x20
call [ebx + device.access_write_bcr]
.L9:
cmp [ebx + device.ltint],0
je .L10
mov ecx,5
call [ebx + device.access_read_csr]
or eax,(1 shl 14)
call [ebx + device.access_write_csr]
.L10:
mov eax,[ebx + device.options]
and eax,PCNET_PORT_PORTSEL
shl eax,7
mov [ebx + device.mode_],ax
mov dword [ebx + device.filter], -1
mov dword [ebx + device.filter+4], -1
 
 
lea eax, [ebx + device.private]
mov ecx, eax
and ecx, 0xFFF ; KolibriOS PAGE SIZE
call GetPgAddr
add eax, ecx
 
push eax
and eax, 0xffff
mov ecx, 1
call [ebx + device.access_write_csr]
pop eax
shr eax,16
mov ecx,2
call [ebx + device.access_write_csr]
 
mov ecx,4
mov eax,0x0915
call [ebx + device.access_write_csr]
 
mov ecx,0
mov eax,1
call [ebx + device.access_write_csr]
 
mov [ebx + device.tx_full],0
mov [ebx + device.cur_rx],0
mov [ebx + device.cur_tx],0
mov [ebx + device.dirty_rx],0
mov [ebx + device.dirty_tx],0
 
mov ecx,100
.L11:
push ecx
xor ecx,ecx
call [ebx + device.access_read_csr]
pop ecx
test ax,0x100
jnz .L12
loop .L11
.L12:
 
DEBUGF 1,"hardware reset\n"
xor ecx, ecx
mov eax, 0x0002
call [ebx + device.access_write_csr]
 
xor ecx, ecx
call [ebx + device.access_read_csr]
 
call read_mac
 
xor ecx, ecx
mov eax, PCNET_CSR_INTEN or PCNET_CSR_START
call [ebx + device.access_write_csr]
 
DEBUGF 1,"PCNET reset complete\n"
xor eax, eax
ret
 
 
 
 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Transmit ;;
;; ;;
;; In: buffer pointer in [esp] ;;
;; size of buffer in [esp+4] ;;
;; pointer to device structure in ebx ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
align 4
transmit:
DEBUGF 1,"Transmitting packet, buffer:%x, size:%u\n",[esp],[esp+4]
mov eax, [esp]
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+06]:2,[eax+07]:2,[eax+08]:2,[eax+09]:2,[eax+10]:2,[eax+11]:2,\
[eax+13]:2,[eax+12]:2
 
cmp dword [esp+4], 1514
jg .finish ; packet is too long
cmp dword [esp+4], 60
jl .finish ; packet is too short
 
; check descriptor
DEBUGF 1,"Checking descriptor, "
movzx eax, [ebx + device.cur_tx]
mov edx, buf_head.size ;;PCNET_PKT_BUF_SZ
mul dx
mov edi, [ebx + device.tx_buffer]
add edi, eax
 
mov edx, [ebx + device.io_addr]
 
mov ecx, [esp+4]
neg cx ;;;;
mov [edi + buf_head.length], cx
mov [edi + buf_head.misc], 0
 
mov eax, [esp]
mov ecx, eax
and ecx, 0xfff
call GetPgAddr
add eax, ecx
mov [edi + buf_head.base], eax
mov [edi + buf_head.status], 0x8300
 
; trigger an immediate send
mov ecx, 0 ; CSR0
call [ebx + device.access_read_csr]
or eax, PCNET_CSR_TX
call [ebx + device.access_write_csr]
 
; get next descriptor 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, ...
inc [ebx + device.cur_tx]
and [ebx + device.cur_tx], 3
DEBUGF 2," - Packet Sent! "
 
.finish:
DEBUGF 2," - Done!\n"
;;; call KernelFree
add esp, 4+4 ; pop (balance stack)
 
ret
 
 
 
 
 
;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Interrupt handler ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;
 
align 4
int_handler:
 
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
 
mov esi, PCNET_LIST
mov ecx, [PCNET_DEV]
test ecx, ecx
jz .abort
.nextdevice:
mov ebx, dword [esi]
mov edx, [ebx + device.io_addr] ; get IRQ reason
 
push ecx
mov ecx, 0 ; CSR0
call [ebx + device.access_read_csr]
pop ecx
 
test ax , ax
jnz .got_it
 
add esi, 4
loop .nextdevice
 
ret ; If no device was found, abort (The irq was probably for a device, not registered to this driver
 
.got_it:
 
;-------------------------------------------------------
; Received packet ok?
 
test ax, PCNET_CSR_RINT
jz @f
 
movzx eax, [ebx + device.cur_rx]
; and eax, PCNET_RX_RING_MOD_MASK
mov edi, eax
 
imul esi, eax, PCNET_PKT_BUF_SZ ;
add esi, [ebx + device.rx_buffer] ; esi now points to rx buffer
 
shl edi, 4 ; desc * 16 (16 is size of one ring entry)
add edi, [ebx + device.rx_ring] ; edi now points to current rx ring entry
 
mov cx , [edi + buf_head.status]
 
test cx , PCNET_RXSTAT_OWN ; If this bit is set, the controller OWN's the packet, if not, we do
jnz .abort
 
cmp cx , PCNET_RXSTAT_ENP
jz .abort
 
cmp cx , PCNET_RXSTAT_STP
jz .abort
 
movzx ecx, [ebx + buf_head.length] ; get packet length in ecx
and ecx, 0xfff ;
sub ecx, 4 ;
 
stdcall KernelAlloc, ecx ; Allocate a buffer to put packet into
test eax, eax ; Test if we allocated succesfully
jz .abort ;
 
push ecx ; for eth_receiver
push eax ;
 
xchg edi, eax
push ecx
shr ecx, 2
cld
rep movsd
pop ecx
and ecx, 3
rep movsb
 
mov word [eax + buf_head.length], PCNET_PKT_BUF_SZ_NEG
or word [eax + buf_head.status], PCNET_RXSTAT_OWN ; Set OWN bit back to 1 (controller may write to tx-buffer again now)
 
inc [ebx + device.cur_rx] ; update descriptor
and [ebx + device.cur_rx], 3 ;
 
jmp EthReceiver ; Send the copied packet to kernel
 
.abort:
 
@@:
 
ret
 
 
 
 
;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Write MAC address ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;
 
align 4
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
 
mov edx, [ebx + device.io_addr]
add dx, 2
xor eax, eax
 
mov ecx, PCNET_CSR_PAR0
@@:
pop ax
call [ebx + device.access_write_csr]
DEBUGF 1,"."
inc ecx
cmp ecx, PCNET_CSR_PAR2
jl @r
 
DEBUGF 1,"\n"
 
; Notice this procedure does not ret, but continues to read_mac instead.
 
;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Read MAC address ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;
 
read_mac: ; T- OK
DEBUGF 1,"Reading MAC"
 
mov edx, [ebx + device.io_addr]
add dx, 6
@@:
dec dx
dec dx
in ax, dx
push ax
DEBUGF 1,"."
cmp edx, [ebx + device.io_addr]
jg @r
 
DEBUGF 1," %x-%x-%x-%x-%x-%x\n",[esp+0]:2,[esp+1]:2,[esp+2]:2,[esp+3]:2,[esp+4]:2,[esp+5]:2
 
lea edi, [ebx + device.mac]
pop ax
stosw
pop ax
stosw
pop ax
stosw
 
ret
 
 
switch_to_wio:
 
mov [ebx + device.access_read_csr], wio_read_csr
mov [ebx + device.access_write_csr], wio_write_csr
mov [ebx + device.access_read_bcr], wio_read_bcr
mov [ebx + device.access_write_bcr], wio_write_bcr
mov [ebx + device.access_read_rap], wio_read_rap
mov [ebx + device.access_write_rap], wio_write_rap
mov [ebx + device.access_reset], wio_reset
 
ret
 
switch_to_dwio:
 
mov [ebx + device.access_read_csr], dwio_read_csr
mov [ebx + device.access_write_csr], dwio_write_csr
mov [ebx + device.access_read_bcr], dwio_read_bcr
mov [ebx + device.access_write_bcr], dwio_write_bcr
mov [ebx + device.access_read_rap], dwio_read_rap
mov [ebx + device.access_write_rap], dwio_write_rap
mov [ebx + device.access_reset], dwio_reset
 
ret
 
 
 
 
 
; ecx - index
; return:
; eax - data
wio_read_csr:
 
add edx, PCNET_WIO_RAP
mov ax , cx
out dx , ax
add edx, PCNET_WIO_RDP - PCNET_WIO_RAP
in ax , dx
and eax, 0xffff
sub edx, PCNET_WIO_RDP
 
ret
 
 
; eax - data
; ecx - index
wio_write_csr:
 
add edx, PCNET_WIO_RAP
xchg eax, ecx
out dx , ax
xchg eax, ecx
add edx, PCNET_WIO_RDP - PCNET_WIO_RAP
out dx , ax
sub edx, PCNET_WIO_RDP
 
ret
 
 
; ecx - index
; return:
; eax - data
wio_read_bcr:
 
add edx, PCNET_WIO_RAP
mov ax , cx
out dx , ax
add edx, PCNET_WIO_BDP - PCNET_WIO_RAP
in ax , dx
and eax, 0xffff
sub edx, PCNET_WIO_BDP
 
ret
 
 
; eax - data
; ecx - index
wio_write_bcr:
 
add edx, PCNET_WIO_RAP
xchg eax, ecx
out dx , ax
xchg eax, ecx
add edx, PCNET_WIO_BDP - PCNET_WIO_RAP
out dx , ax
sub edx, PCNET_WIO_BDP
 
ret
 
 
wio_read_rap:
 
add edx, PCNET_WIO_RAP
in ax , dx
and eax, 0xffff
sub edx, PCNET_WIO_RAP
 
ret
 
; eax - val
wio_write_rap:
 
add edx, PCNET_WIO_RAP
out dx , ax
sub edx, PCNET_WIO_RAP
 
ret
 
 
wio_reset:
 
push eax
add edx, PCNET_WIO_RESET
in ax , dx
pop eax
sub edx, PCNET_WIO_RESET
 
ret
 
 
 
; ecx - index
; return:
; eax - data
dwio_read_csr:
 
add edx, PCNET_DWIO_RAP
mov ecx, eax
out dx , eax
add edx, PCNET_DWIO_RDP - PCNET_DWIO_RAP
in eax, dx
and eax, 0xffff
sub edx, PCNET_DWIO_RDP
 
ret
 
 
; ecx - index
; eax - data
dwio_write_csr:
 
add edx, PCNET_DWIO_RAP
xchg eax, ecx
out dx , eax
add edx, PCNET_DWIO_RDP - PCNET_DWIO_RAP
xchg eax, ecx
out dx , eax
sub edx, PCNET_DWIO_RDP
 
ret
 
; ecx - index
; return:
; eax - data
dwio_read_bcr:
 
add edx, PCNET_DWIO_RAP
mov ecx, eax
out dx , eax
add edx, PCNET_DWIO_BDP - PCNET_DWIO_RAP
in eax, dx
and eax, 0xffff
sub edx, PCNET_DWIO_BDP
 
ret
 
 
; ecx - index
; eax - data
dwio_write_bcr:
 
add edx, PCNET_DWIO_RAP
xchg eax, ecx
out dx , eax
add edx, PCNET_DWIO_BDP - PCNET_DWIO_RAP
xchg eax, ecx
out dx , eax
sub edx, PCNET_DWIO_BDP
 
ret
 
 
dwio_read_rap:
 
add edx, PCNET_DWIO_RAP
in eax, dx
and eax, 0xffff
sub edx, PCNET_DWIO_RAP
 
ret
 
 
; eax - val
dwio_write_rap:
 
add edx, PCNET_DWIO_RAP
out dx , eax
sub edx, PCNET_DWIO_RAP
 
ret
 
 
dwio_reset:
 
push eax
add edx, PCNET_DWIO_RESET
in eax, dx
pop eax
sub edx, PCNET_DWIO_RESET
 
ret
 
 
 
adjust_pci_device:
;*******Get current setting************************
movzx edx, byte [ebx + device.pci_dev]
movzx ecx, byte [ebx + device.pci_bus]
stdcall PciRead16, edx ,ecx ,0x04
; ;******see if its already set as bus master********
; and ax,5
; cmp ax,5
; je .Latency
;******Make card a bus master*******
or ax , 5
stdcall PciWrite16, edx ,ecx ,0x04, eax
;******Check latency setting***********
.Latency:
;*******Get current latency setting************************
; mov al, 1 ;read a byte
; mov bh, [pci_dev]
; mov ah, [pci_bus]
; mov bl, 0x0D ;from Lantency Timer Register
; call pci_read_reg
;******see if its aat least 64 clocks********
; cmp ax,64
; jge PCNET_adjust_pci_device_Done
;******Set latency to 32 clocks*******
; mov cx, 64 ;value to write
; mov bh, [pci_dev]
; mov al, 1 ;write a byte
; mov ah, [pci_bus]
; mov bl, 0x0D ;to Lantency Timer Register
; call pci_write_reg
;******Check latency setting***********
.Done:
ret
 
 
 
 
; End of code
 
align 4 ; Place all initialised data here
 
PCNET_DEV dd 0
version dd (5 shl 16) or (API_VERSION and 0xFFFF)
my_service db 'PCnet',0 ; max 16 chars include zero
 
device_l2 db "PCnet/PCI 79C970",0
device_l4 db "PCnet/PCI II 79C970A",0
device_l5 db "PCnet/FAST 79C971",0
device_l6 db "PCnet/FAST+ 79C972",0
device_l7 db "PCnet/FAST III 79C973",0
device_l8 db "PCnet/Home 79C978",0
device_l9 db "PCnet/FAST III 79C975",0
 
options_mapping:
dd PCNET_PORT_ASEL ; 0 Auto-select
dd PCNET_PORT_AUI ; 1 BNC/AUI
dd PCNET_PORT_AUI ; 2 AUI/BNC
dd PCNET_PORT_ASEL ; 3 not supported
dd PCNET_PORT_10BT or PCNET_PORT_FD ; 4 10baseT-FD
dd PCNET_PORT_ASEL ; 5 not supported
dd PCNET_PORT_ASEL ; 6 not supported
dd PCNET_PORT_ASEL ; 7 not supported
dd PCNET_PORT_ASEL ; 8 not supported
dd PCNET_PORT_MII ; 9 MII 10baseT
dd PCNET_PORT_MII or PCNET_PORT_FD ; 10 MII 10baseT-FD
dd PCNET_PORT_MII ; 11 MII (autosel)
dd PCNET_PORT_10BT ; 12 10BaseT
dd PCNET_PORT_MII or PCNET_PORT_100 ; 13 MII 100BaseTx
dd PCNET_PORT_MII or PCNET_PORT_100 or PCNET_PORT_FD ; 14 MII 100BaseTx-FD
dd PCNET_PORT_ASEL ; 15 not supported
 
include_debug_strings ; All data wich FDO uses will be included here
 
section '.data' data readable writable align 16 ; place all uninitialized data place here
 
PCNET_LIST rd MAX_PCNET ; This list contains all pointers to device structures the driver is handling
/kernel/branches/net/kernel.asm
1,6 → 1,6
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; Copyright (C) KolibriOS team 2004-2008. All rights reserved.
;; Copyright (C) KolibriOS team 2004-2009. All rights reserved.
;; PROGRAMMING:
;; Ivan Poddubny
;; Marat Zakiyanov (Mario79)
/kernel/branches/net/network/ARP.inc
1,23 → 1,22
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2008. All rights reserved. ;;
;; Copyright (C) KolibriOS team 2004-2009. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;; ARP.INC ;;
;; ;;
;; Address Resolution Protocol ;;
;; Part of the tcp/ip network stack for KolibriOS ;;
;; ;;
;; This file contains the following: ;;
;; arp_table_manager - Manages an ARPTable ;;
;; arp_request - Sends an ARP request on the ethernet ;;
;; arp_handler - Called when an ARP packet is received ;;
;; Based on the work of [Johnny_B] and [smb] ;;
;; ;;
;; Changes history: ;;
;; 22.09.2003 - [Mike Hibbett] : mikeh@oceanfree.net ;;
;; 11.11.2006 - [Johnny_B] and [smb] ;;
;; Written by hidnplayr@kolibrios.org ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; GNU GENERAL PUBLIC LICENSE ;;
;; Version 2, June 1991 ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
 
$Revision: 983 $
 
 
26,6 → 25,9
ARP_AWAITING_RESPONSE equ 2
ARP_RESPONSE_TIMEOUT equ 3
 
ARP_REQUEST_TTL = 20 ; in seconds
ARP_ENTRY_TTL = 30 ; in seconds
 
ETHER_ARP equ 0x0608
 
ARP_REQ_OPCODE equ 0x0100 ; request
79,7 → 81,18
 
 
 
;-----------------------------------------------------------------
;
; ARP_init
;
; This function resets all ARP variables
;
; IN: /
; OUT: /
;
;-----------------------------------------------------------------
 
align 4
ARP_init:
 
xor eax, eax
93,176 → 106,24
ret
 
 
 
 
;***************************************************************************
; Function
; arp_table_manager [by Johnny_B]
;-----------------------------------------------------------------
;
; Description
; Does a most required operations with ARP-table
; IN:
; Operation: see Opcode's constants below
; Index: Index of entry in the ARP-table
; Extra: Extra parameter for some Opcodes
; OUT:
; EAX = Returned value depends on opcodes, more detailed see below
; ARP_IP_to_MAC
;
;***************************************************************************
;Opcode's constants
ARP_TABLE_ADD equ 1
ARP_TABLE_IP_TO_MAC equ 5
; This function resets all ARP variables
;
; IN: eax = IPv4 address
; OUT: eax = -1 on error, else eax = first two bytes of mac
; ( high 16 bits are zero)
; ebx = last four bytes of mac ; TODO: special eax value for 'request send'
;
;-----------------------------------------------------------------
 
;Index's constants
EXTRA_IS_ARP_PACKET_PTR equ 0 ;if Extra contain pointer to ARP_Packet
EXTRA_IS_ARP_ENTRY_PTR equ -1 ;if Extra contain pointer to ARP_ENTRY
 
align 4
proc arp_table_manager stdcall uses ebx esi edi ecx edx, Opcode:DWORD,Index:DWORD,Extra:DWORD
ARP_IP_to_MAC:
 
mov ebx, ARPTable ;ARPTable base
mov ecx, dword[NumARP] ;ARP-entries counter
DEBUGF 1,"ARP_IP_to_MAC\n"
 
mov eax, dword[Opcode]
 
 
DEBUGF 1,"ARP table manager opcode:%u numARP:%u\n",eax,ecx
 
cmp eax, ARP_TABLE_ADD
je .add
 
cmp eax, ARP_TABLE_IP_TO_MAC
je .ip_to_mac
 
jmp .exit ;if unknown opcode
 
 
;;BEGIN ADD
;;Description: it adds an entry in the table. If ARP-table already
;; contains same IP, it will be updated.
;;IN: Operation: ARP_TABLE_ADD
;; Index: specifies what contains Extra-parameter
;; Extra: if Index==EXTRA_IS_ARP_Packet_PTR,
;; then Extra contains pointer to ARP_Packet,
;; otherwise Extra contains pointer to ARP_ENTRY
;;OUT:
;; EAX=index of entry, that has been added
;;
.add:
 
DEBUGF 1,"1"
 
sub esp, ARP_ENTRY.size ;Allocate ARP_ENTRY_SIZE byte in stack
 
mov esi, [Extra] ;pointer
mov edi, [Index] ;opcode
 
cmp edi, EXTRA_IS_ARP_PACKET_PTR
je .ARP_Packet_to_entry ;if Extra contain ptr to ARP_Packet and we have to form arp-entry
;else it contain ptr to arp-entry
 
DEBUGF 1,"2"
 
cld
; esi already has been loaded
mov edi, esp ;ebx + eax=ARPTable_base + ARP-entry_base(where we will add)
mov ecx,ARP_ENTRY.size/2 ;ARP_ENTRY_SIZE must be even number!!!
rep movsw ;copy
jmp .search
 
.ARP_Packet_to_entry:
 
DEBUGF 1,"3"
mov edx, dword[esi + ARP_Packet.SenderIP] ;esi=base of ARP_Packet
mov [esp + ARP_ENTRY.IP], edx
 
cld
lea esi, [esi + ARP_Packet.SenderMAC]
lea edi, [esp + ARP_ENTRY.MAC]
movsd
movsw
mov word[esp + ARP_ENTRY.Status], ARP_VALID_MAPPING ; specify the type - a valid entry
mov word[esp + ARP_ENTRY.TTL], 0x0E10 ; = 1 hour
 
.search:
 
DEBUGF 1,"4"
mov edx, dword[esp + ARP_ENTRY.IP] ;edx=IP-address, which we'll search
mov ecx, dword[NumARP] ;ecx=ARP-entries counter
jecxz .add_to_end ;if ARP-entries number == 0
imul eax, ecx, ARP_ENTRY.size ;eax=current table size(in bytes)
@@:
sub eax, ARP_ENTRY.size
cmp dword[ebx + eax + ARP_ENTRY.IP], edx
loopnz @b
; jz .replace ; found, replace existing entry, ptr to it is in eax
 
.add_to_end:
;
; DEBUGF 1,"5\n"
; ;else add to end
; or eax,-1 ;set eax=0xFFFFFFFF if adding is impossible
; mov ecx, dword[NumARP]
; cmp ecx, ARP_TABLE_SIZE
; je .add_exit ;if arp-entries number is equal to arp-table maxsize
 
; imul eax, dword[NumARP], ARP_ENTRY.size ;eax=ptr to end of ARPTable
; inc dword [NumARP] ;increase ARP-entries counter
 
; .replace:
DEBUGF 1,"Updating ARP entry: %x-%x-%x-%x-%x-%x = %u.%u.%u.%u to slot:%u\n",\
[esp + ARP_ENTRY.MAC]:2,[esp + ARP_ENTRY.MAC+1]:2,[esp + ARP_ENTRY.MAC+2]:2,[esp + ARP_ENTRY.MAC+3]:2,[esp + ARP_ENTRY.MAC+4]:2,[esp + ARP_ENTRY.MAC+5]:2,\
[esp + ARP_ENTRY.IP]:1,[esp + ARP_ENTRY.IP+1]:1,[esp + ARP_ENTRY.IP+2]:1,[esp + ARP_ENTRY.IP+3]:1,eax
 
cld
mov esi, esp ;esp=base of ARP-entry, that will be added
lea edi, [ebx + eax] ;ebx + eax=ARPTable_base + ARP-entry_base(where we will add)
mov ecx,ARP_ENTRY.size/2 ;ARP_ENTRY_SIZE must be even number!!!
rep movsw
 
mov ecx, ARP_ENTRY.size
xor edx, edx ;"div" takes operand from EDX:EAX
div ecx ;eax=index of entry, which has been added
 
 
 
.add_exit:
 
add esp, ARP_ENTRY.size ;free stack
jmp .exit
;;END ADD
 
 
 
;;BEGIN IP_TO_MAC
;;Description: it gets an IP from Index, scans each entry in the table and writes
;; MAC, that relates to specified IP, into buffer specified in Extra.
;; And if it cannot find an IP-address in the table, it does an ARP-request of that.
;;IN: Operation: ARP_TABLE_IP_TO_MAC
;; Index: IP that should be transformed into MAC
;; Extra: pointer to buffer where will be written the MAC-address.
;;OUT:
;; EAX=ARP table entry status code.
;; If EAX==ARP_NO_ENTRY, IP isn't found in the table and we have sent the request.
;; If EAX==ARP_AWAITING_RESPONSE, we wait the response from remote system.
;; If EAX==ARP_RESPONSE_TIMEOUT, remote system not responds too long.
;; If EAX==ARP_VALID_MAPPING, all is ok, we've got a true MAC.
;;
;; If MAC will equal to a zero, in the buffer. It means, that IP-address was not yet
;; resolved, or that doesn't exist. I recommend you, to do at most 3-5 calls of this
;; function with 1sec delay. sure, only if it not return a valid MAC after a first call.
;;
.ip_to_mac:
 
DEBUGF 1,"Trying to find MAC for %u.%u.%u.%u\n",[Index]:1,[Index+1]:1,[Index+2]:1,[Index+3]:1
 
xor eax, eax
mov edi, dword[Extra]
cld
stosd
stosw
 
 
; first, check destination IP to see if it is on 'this' network.
; The test is:
; if ( destIP & subnet_mask == stack_ip & subnet_mask )
270,187 → 131,133
; else
; destination is remote, so pass to gateway
 
xor edx, edx ; TODO: find device num in edx
 
;;; TODO: get device number ! (in edx)
xor edx, edx
mov ebx, [IP_LIST+edx]
and ebx, [SUBNET_LIST+edx]
mov ecx, eax
and ecx, [SUBNET_LIST+edx]
cmp ecx, ebx
je .local
 
mov eax, [Index] ;eax=required IP
mov esi, eax
and esi, [SUBNET_LIST+edx]
mov ecx, [IP_LIST+edx]
and ecx, [SUBNET_LIST+edx]
cmp esi, ecx
je @f ;if we and target IP are located in the same network
mov eax, [GATEWAY_LIST+edx]
mov [Index], eax
DEBUGF 1,"IP is not on subnet, using %u.%u.%u.%u instead\n",[Index]:1,[Index+1]:1,[Index+2]:1,[Index+3]:1
@@:
DEBUGF 1,"requested IP is not on subnet, using gateway\n"
 
cmp dword[NumARP], 0
je .ip_to_mac_send_request ;if ARP-table not contain an entries, we have to request IP.
;EAX will be containing a zero, it's equal to ARP_NO_ENTRY
.local:
; try to find it on the list
mov ecx, [NumARP]
jz .not_in_list
mov esi, ARPTable + ARP_ENTRY.IP
.scan_loop:
scasd
jz .found_it
add esi, ARP_ENTRY.size - 4
loop .scan_loop
.not_in_list:
 
mov ecx, dword[NumARP]
imul esi, ecx, ARP_ENTRY.size ;esi=current ARP-table size
DEBUGF 1,"IP not found on list, preparing for ARP request\n"
 
@@:
sub esi, ARP_ENTRY.size
cmp [ebx + esi + ARP_ENTRY.IP], eax ; ebx=ARPTable base
loopnz @b ; Return back if non match
jnz .ip_to_mac_send_request ; and request IP->MAC if none found in the table
; if not, reserve an entry in list and send an ARP request packet
 
; Return the entry status in eax
movzx eax, word[ebx + esi + ARP_ENTRY.Status]
push eax
 
DEBUGF 1,"MAC found: %x-%x-%x-%x-%x-%x status:%x in slot:%u\n",\
[ebx + esi + ARP_ENTRY.MAC]:2,[ebx + esi + ARP_ENTRY.MAC+1]:2,[ebx + esi + ARP_ENTRY.MAC+2]:2,[ebx + esi + ARP_ENTRY.MAC+3]:2,[ebx + esi + ARP_ENTRY.MAC+4]:2,[ebx + esi + ARP_ENTRY.MAC+5]:2, ax, esi
push word ARP_REQUEST_TTL
push word ARP_AWAITING_RESPONSE
push dword 0
push word 0
push eax
call ARP_add_entry
 
; esi holds index
cld
lea esi, [ebx + esi + ARP_ENTRY.MAC]
mov edi, [Extra] ;edi=ptr to buffer for write MAC
movsd
movsw
jmp .exit
cmp eax, -1
je .full
 
.ip_to_mac_send_request:
;;; TODO: get device number ! (in edx)
xor edx, edx
mov edx, [ETH_DRV_LIST + 4*edx]
lea ecx, [edx + ETH_DEVICE.mac]
pop eax
call ARP_create_request
 
stdcall arp_request,[Index],[IP_LIST+edx],ecx ;TargetIP,SenderIP_ptr,SenderMAC_ptr
mov eax, ARP_NO_ENTRY
jmp .exit
ret
 
;;END IP_TO_MAC
.found_it:
DEBUGF 1,"Found MAC! (%u-%u-%u-%u-%u-%u)\n",[esi+0]:2,[esi+1]:2,[esi+2]:2,[esi+3]:2,[esi+4]:2,[esi+5]:2
movzx eax, word [esi]
mov ebx, [esi+2]
 
.exit:
ret
endp
 
.full:
add esp, 4
mov eax, -1
ret
 
;***************************************************************************
; Function
; arp_request [by Johnny_B]
 
;---------------------------------------------------------------------------
;
; Description
; Sends an ARP request on the ethernet
; IN:
; TargetIP : requested IP address
; SenderIP_ptr : POINTER to sender's IP address(our system's address)
; SenderMAC_ptr : POINTER to sender's MAC address(our system's address)
; OUT:
; EAX=0 (if all is ok), otherwise EAX is not defined
; ARP_create_packet
;
; EBX,ESI,EDI will be saved
; IN: ip in eax
;
;***************************************************************************
proc arp_request stdcall uses ebx esi edi,\
TargetIP:DWORD, SenderIP_ptr:DWORD, SenderMAC_ptr:DWORD
; OUT: /
;
;---------------------------------------------------------------------------
 
DEBUGF 1,"Create ARP request\n"
 
align 4
ARP_create_request:
 
stdcall kernel_alloc, 60 ; minimum eth packet size
test eax, eax
jz .exit
DEBUGF 1,"Create ARP Packet\n"
 
mov ebx, eax
call IPv4_dest_to_dev
 
mov word [ebx + ETH_FRAME.Data + ARP_Packet.HardwareType], 0x0100 ;Ethernet
mov word [ebx + ETH_FRAME.Data + ARP_Packet.ProtocolType], 0x0008 ;IP
mov byte [ebx + ETH_FRAME.Data + ARP_Packet.HardwareSize], 0x06 ;MAC-addr length
mov byte [ebx + ETH_FRAME.Data + ARP_Packet.ProtocolSize], 0x04 ;IP-addr length
mov word [ebx + ETH_FRAME.Data + ARP_Packet.Opcode], 0x0100 ;Request
push eax ; DestIP
mov eax, [IP_LIST+4*edi] ; senderIP
push eax
 
DEBUGF 1,"1"
mov edi, [ETH_DRV_LIST + 4*edi]
lea eax, [edi + ETH_DEVICE.mac]
mov ebx, ETH_BROADCAST
mov ecx, 60 ; minimum packet size
mov edx, edi ;;;
mov di , ETHER_ARP
call ETH_create_Packet
cmp edi, -1
je .exit
 
cld
mov esi, [SenderMAC_ptr]
lea edi, [ebx + ETH_FRAME.Data + ARP_Packet.SenderMAC] ;Our MAC-addr
movsd
movsw
mov word [edi + ARP_Packet.HardwareType], 0x0100 ;Ethernet
mov word [edi + ARP_Packet.ProtocolType], 0x0008 ;IP
mov byte [edi + ARP_Packet.HardwareSize], 6 ;MAC-addr length
mov byte [edi + ARP_Packet.ProtocolSize], 4 ;IP-addr length
mov word [edi + ARP_Packet.Opcode], ARP_REQ_OPCODE ;Request
 
DEBUGF 1,"2"
add edi, ARP_Packet.SenderMAC ; sendermac
lea esi, [edx + ETH_DEVICE.mac] ;
movsw ;
movsd ;
 
mov esi, [SenderIP_ptr]
mov [ebx + ETH_FRAME.Data + ARP_Packet.SenderIP], esi ;Our IP-addr
; movsd
pop eax
stosd ;
 
DEBUGF 1,"3"
xor eax, eax ; destmac
movsw ;
movsw ;
 
lea edi, [ebx + ETH_FRAME.Data + ARP_Packet.TargetMAC] ; Required MAC-addr
xor eax, eax
stosd
stosw
pop eax
movsd ;
 
DEBUGF 1,"4"
DEBUGF 1,"ARP Packet for device %x created successfully\n", edx
 
lea edi, [ebx + ETH_FRAME.DstMAC]
stosd
stosw
call esi
 
DEBUGF 1,"5"
inc [ARP_PACKETS_TX+4*edi]
 
mov esi, [TargetIP]
mov dword [ebx + ETH_FRAME.Data + ARP_Packet.TargetIP], esi ;Required IP-addr(we get it as function parameter)
ret
 
 
DEBUGF 1,"6"
 
mov esi, [SenderMAC_ptr]
lea edi, [ebx + ETH_FRAME.SrcMAC]
movsd
movsw
 
DEBUGF 1,"7"
 
mov ax , ETHER_ARP
stosw
 
DEBUGF 1,"8"
 
;;; TODO: get device number in edx !!
xor edx, edx
shl edx, 2
 
inc [ARP_PACKETS_TX+edx]
 
push dword .returnaddr
push dword 60
push ebx
mov ebx, [ETH_DRV_LIST + edx]
jmp [ebx + ETH_DEVICE.transmit]
.returnaddr:
 
; Add an entry in the ARP table, awaiting response
sub esp, ARP_ENTRY.size ;allocate memory for ARP-entry
 
mov esi, dword[TargetIP]
mov dword[esp + ARP_ENTRY.IP],esi
 
lea edi, [esp + ARP_ENTRY.MAC]
xor eax, eax
stosd
stosw
 
mov word[esp + ARP_ENTRY.Status], ARP_AWAITING_RESPONSE
mov word[esp + ARP_ENTRY.TTL], 10 ; 10 seconds
 
stdcall arp_table_manager,ARP_TABLE_ADD,EXTRA_IS_ARP_ENTRY_PTR,esp
add esp, ARP_ENTRY.size ; free memory
 
.exit:
 
DEBUGF 1,"ARP request - end\n"
add esp, 8
DEBUGF 1,"Create ARP Packet - failed\n"
mov eax, -1
ret
endp
 
 
 
 
 
;---------------------------------------------------------------------------
;
; ARP_decrease_entry_ttls
512,7 → 319,82
 
ret
 
;---------------------------------------------------------------------------
;
; ARP_add_entry (or update)
;
; IN: arp entry in stack: esp .IP
; esp+4 .MAC
; esp+10 .Status
; esp+12 .TTL
; esp+14
;
; OUT: eax = entry #, -1 on error
;
;---------------------------------------------------------------------------
 
; TODO: use a mutex
 
align 4
ARP_add_entry:
 
mov ecx, [NumARP]
test ecx, ecx
jz .add
 
mov eax, dword[esp + ARP_ENTRY.MAC]
mov bx , word[esp + ARP_ENTRY.MAC + 4]
mov esi, ARPTable
 
.loop:
cmp dword [esi + ARP_ENTRY.MAC], eax
jne .maybe_next
cmp word [esi + ARP_ENTRY.MAC + 4], bx
jne .maybe_next
 
cmp dword[esi + ARP_ENTRY.TTL], 0xFFFF ; static entry
jne .notstatic
cmp dword[esp + ARP_ENTRY.TTL], 0xFFFF
jne .exit
.notstatic:
 
mov ebx, [NumARP]
xchg ebx, ecx
sub ecx, ebx
jmp .add
 
.maybe_next:
add esi, ARP_ENTRY.size
loop .loop
 
mov ecx, [NumARP]
cmp ecx, ARP_TABLE_SIZE
jge .full
 
.add:
 
push ecx
imul ecx, ARP_ENTRY.size
lea edi, [ecx + ARPTable]
lea esi, [esp + 4]
mov ecx, ARP_ENTRY.size/2
repz movsw
 
inc [NumARP]
pop eax
 
.exit:
 
add esp, 14
ret
 
.full:
 
mov eax, -1
jmp .exit
 
 
 
;---------------------------------------------------------------------------
;
; ARP_del_entry
537,13 → 419,12
cld
rep movsw
 
dec dword[NumARP] ;decrease arp-entries counter
dec [NumARP] ;decrease arp-entries counter
ret
 
 
 
 
 
;-----------------------------------------------------
;
; ARP_Handler:
557,22 → 438,53
; OUT: /
;
;-----------------------------------------------------
 
align 4
ARP_Handler:
ARP_handler:
 
DEBUGF 1,"ARP_Handler - start\n"
cmp ecx, 28
jl .exit
 
; Is this a REQUEST?
; Is this a request for My Host IP
; Yes - So construct a response message.
; Send this message to the ethernet card for transmission
cmp word [edx + ARP_Packet.Opcode], ARP_REP_OPCODE ; Is this a reply packet?
jne .maybe_request
 
; push ebx edx
stdcall arp_table_manager, ARP_TABLE_ADD, EXTRA_IS_ARP_PACKET_PTR, edx
; pop edx ebx
mov ecx, [NumARP]
test ecx, ecx
jz .exit
 
mov eax, [esp]
mov eax, [eax + ARP_Packet.SenderIP]
mov esi, ARPTable+ARP_ENTRY.IP
 
.loop:
scasd
jz .gotit
add esi, ARP_ENTRY.size-4
loop .loop
 
jmp .exit
 
.gotit:
cmp [esi-4+ARP_ENTRY.Status], 0x0300 ;if it is a static entry, dont touch it
je .exit
 
mov [esi-4+ARP_ENTRY.Status], ARP_VALID_MAPPING
mov [esi+ARP_ENTRY.TTL-4], ARP_ENTRY_TTL
 
mov ebx, [esp]
mov eax, dword [ebx + ARP_Packet.SenderMAC]
mov dword [esi+ARP_ENTRY.MAC-4], eax
mov ax , word [ebx + ARP_Packet.SenderMAC + 4]
mov word [esi+ARP_ENTRY.MAC-4+4], ax
 
jmp .exit
 
 
;------
 
 
.maybe_request:
cmp word [edx + ARP_Packet.Opcode], ARP_REQ_OPCODE ; Is this a request packet?
jne .exit
 
591,10 → 503,8
push eax
push edi
 
; DEBUGF 1,"ETH_ARP_Handler - request for %u.%u.%u.%u\n",[edi+0]:1,[edi+1]:1,[edi+2]:1,[edi+3]:1
 
; OK, it is a request for one of our MAC addresses. Build the frame and send it
; We can reuse the buffer.
; We can reuse the buffer. (faster then using ARP_create_packet)
 
cld
lea esi, [edx + ARP_Packet.SenderMAC]
623,8 → 533,8
lea esi, [edx + ARP_Packet.SenderMAC]
movsd
movsw
mov ax , ETHER_ARP
stosw
; mov ax , ETHER_ARP
; stosw
 
jmp ETH_Sender ; And send it!
 
672,7 → 582,6
jz .remove ; 5
dec bl
 
 
.error:
mov eax, -1
ret
697,9 → 606,11
 
.write:
; TODO: write code
; call ARP_write_entry
ret
 
.remove:
; TODO: write code
mov esi, eax
call ARP_del_entry
ret
 
/kernel/branches/net/network/IPv4.inc
1,6 → 1,6
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2008. All rights reserved. ;;
;; Copyright (C) KolibriOS team 2004-2009. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;; IP.INC ;;
85,7 → 85,9
 
or eax, -1
mov edi, BROADCAST
mov ecx, 1+4*MAX_IP
stosd
xor eax, eax
mov ecx, 4*MAX_IP
rep stosd
 
xor eax, eax
116,7 → 118,7
;-----------------------------------------------------------------
 
align 4
IPv4_Handler:
IPv4_handler:
 
DEBUGF 1,"IP_Handler - start\n"
mov cx , [edx + IPv4_Packet.HeaderChecksum]
186,13 → 188,13
pop edx ; Offset to data (tcp/udp/icmp/.. Packet)
 
cmp al , IP_PROTO_TCP
; je TCP_Handler
; je TCP_handler
 
cmp al , IP_PROTO_UDP
je UDP_Handler
je UDP_handler
 
cmp al , IP_PROTO_ICMP
je ICMP_Handler
je ICMP_handler
 
DEBUGF 1,"IP_Handler - unknown protocol:%u\n",al
 
391,14 → 393,14
mov al , [edx + IPv4_Packet.Protocol]
pop edx ; Offset to data (tcp/udp/icmp/.. Packet)
 
; cmp al , IP_PROTO_TCP
; je TCP_Handler
cmp al , IP_PROTO_TCP
; je TCP_handler
 
cmp al , IP_PROTO_UDP
je UDP_Handler
je UDP_handler
 
cmp al , IP_PROTO_ICMP
je ICMP_Handler_fragments
je ICMP_handler_fragments
 
DEBUGF 1,"IP_Handler - unknown protocol:%u\n",al
 
505,7 → 507,7
;;; TODO: create fragmented packets
 
align 4
IPv4_create_Packet:
IPv4_create_packet:
 
DEBUGF 1,"Create IPv4 Packet\n"
 
515,12 → 517,11
cmp eax, -1
je .broadcast ; If it is broadcast, just send
 
push eax
stdcall arp_table_manager, ARP_TABLE_IP_TO_MAC, eax, temp_dstmac ;opcode,IP,MAC_ptr - Get the MAC address.
cmp eax, ARP_NO_ENTRY
pop eax
jne .send
call ARP_IP_to_MAC
 
cmp eax, -1
jne .found
 
DEBUGF 1,"Create IPv4 Packet - ARP entry not found!\n"
 
; TODO: QUEUE!
528,9 → 529,15
 
ret
 
.found:
push ax
push ebx
 
jmp .send
 
.broadcast:
mov dword [temp_dstmac], -1
mov word [temp_dstmac+4], -1
push word -1
push dword -1
 
 
.send:
539,9 → 546,10
inc [IP_PACKETS_TX+4*edi]
mov edi, [ETH_DRV_LIST + 4*edi]
lea eax, [edi + ETH_DEVICE.mac]
mov ebx, temp_dstmac
lea ebx, [esp+16]
mov ecx, [esp+12]
add ecx, IPv4_Packet.DataOrOptional
mov edx, edi ;;;
mov di , ETHER_IPv4
call ETH_create_Packet ; TODO: figure out a way to make this work with other protocols too
cmp edi, -1
572,10 → 580,12
 
DEBUGF 1,"IPv4 Packet for device %x created successfully\n", edx
 
add esp, 6
 
ret
 
.exit:
add esp, 16
add esp, 16+6
.exit_:
DEBUGF 1,"Create IPv4 Packet - failed\n"
or edi, -1
582,11 → 592,7
ret
 
 
uglobal
temp_dstmac dp ? ; TODO: place this in stack instead!
endg
 
 
;---------------------------------------------------------------------------
;
; IPv4_dest_to_dev
/kernel/branches/net/network/ethernet.inc
1,6 → 1,6
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2008. All rights reserved. ;;
;; Copyright (C) KolibriOS team 2004-2009. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;; ETHERNET.INC ;;
46,6 → 46,12
 
 
align 4
iglobal
 
ETH_BROADCAST dp 0xffffffffffff
endg
 
align 4
uglobal
 
ETH_RUNNING dd ?
230,7 → 236,7
;-------------------------------------------------------------
 
align 4
ETH_Handler:
ETH_handler:
 
get_from_queue ETH_IN_QUEUE, ETH_QUEUE_SIZE, .gohome
 
243,10 → 249,10
mov ax , [eax + ETH_FRAME.Type]
 
cmp ax, ETHER_IPv4
je IPv4_Handler
je IPv4_handler
 
cmp ax, ETHER_ARP
je ARP_Handler
je ARP_handler
 
DEBUGF 1,"Unknown ethernet packet type %x\n", ax
 
377,19 → 383,15
pop ecx
pop edx
 
DEBUGF 1,"1"
mov edi, eax
pop esi
movsd
movsw
DEBUGF 1,"2"
pop esi
movsd
movsw
DEBUGF 1,"3"
pop ax
stosw
DEBUGF 1,"4"
 
lea eax, [edi - ETH_FRAME.Data] ; Set eax to buffer start
mov ebx, ecx ; Set ebx to complete buffer size
/kernel/branches/net/network/icmp.inc
1,6 → 1,6
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2008. All rights reserved. ;;
;; Copyright (C) KolibriOS team 2004-2009. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;; ICMP.INC ;;
146,7 → 146,7
;--------------------------------
 
align 4
ICMP_Handler: ;TODO: works only on pure ethernet right now !
ICMP_handler: ;TODO: works only on pure ethernet right now !
 
DEBUGF 1,"ICMP_Handler - start\n"
cmp byte [edx + ICMP_Packet.Type], ICMP_ECHO ; Is this an echo request?
318,7 → 318,7
;--------------------------------
 
align 4
ICMP_Handler_fragments: ; works only on pure ethernet right now !
ICMP_handler_fragments: ; works only on pure ethernet right now !
 
DEBUGF 1,"ICMP_Handler_fragments - start\n"
 
345,7 → 345,7
shl edx, 16
mov dx , ICMP_ECHOREPLY shl 8 + 0 ; Type + Code
 
call ICMP_create_Packet
call ICMP_create_packet
 
.dump:
DEBUGF 1,"ICMP_Handler_fragments - end\n"
372,7 → 372,7
;-----------------------------------------------------------------
 
align 4
ICMP_create_Packet:
ICMP_create_packet:
 
DEBUGF 1,"Create ICMP Packet\n"
 
382,7 → 382,7
mov di , IP_PROTO_ICMP
shr edx, 16
 
call IPv4_create_Packet
call IPv4_create_packet
 
cmp edi, -1
je .exit
/kernel/branches/net/network/queue.inc
1,6 → 1,6
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2008. All rights reserved. ;;
;; Copyright (C) KolibriOS team 2004-2009. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;; queue.inc ;;
/kernel/branches/net/network/socket.inc
1,6 → 1,6
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2008. All rights reserved. ;;
;; Copyright (C) KolibriOS team 2004-2009. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;; SOCKET.INC ;;
24,24 → 24,25
.PID dd ? ; application process id
.Domain dd ? ; INET/UNIX/..
.Type dd ? ; RAW/UDP/TCP/...
.Protocol dd ? ; ICMP/IPv4/ARP/
.LocalIP dd ? ; local IP address
.RemoteIP dd ? ; remote IP address
.LocalPort dw ? ; local port
.RemotePort dw ? ; remote port
; .OrigRemoteIP dd ? ; original remote IP address (used to reset to LISTEN state)
; .OrigRemotePort dw ? ; original remote port (used to reset to LISTEN state)
.OrigRemoteIP dd ? ; original remote IP address (used to reset to LISTEN state)
.OrigRemotePort dw ? ; original remote port (used to reset to LISTEN state)
.rxDataCount dd ? ; rx data count
; .TCBState dd ? ; TCB state
; .TCBTimer dd ? ; TCB timer (seconds)
; .ISS dd ? ; initial send sequence
; .IRS dd ? ; initial receive sequence
; .SND_UNA dd ? ; sequence number of unack'ed sent Packets
; .SND_NXT dd ? ; bext send sequence number to use
; .SND_WND dd ? ; send window
; .RCV_NXT dd ? ; next receive sequence number to use
; .RCV_WND dd ? ; receive window
; .SEG_LEN dd ? ; segment length
; .SEG_WND dd ? ; segment window
.TCBState dd ? ; TCB state
.TCBTimer dd ? ; TCB timer (seconds)
.ISS dd ? ; initial send sequence
.IRS dd ? ; initial receive sequence
.SND_UNA dd ? ; sequence number of unack'ed sent Packets
.SND_NXT dd ? ; bext send sequence number to use
.SND_WND dd ? ; send window
.RCV_NXT dd ? ; next receive sequence number to use
.RCV_WND dd ? ; receive window
.SEG_LEN dd ? ; segment length
.SEG_WND dd ? ; segment window
.wndsizeTimer dd ? ; window size timer
.lock dd ? ; lock mutex
.backlog dw ? ; Backlog
125,7 → 126,7
;
; IN: domain in ecx
; type in edx
; set esi to zero, it is reserved for future use
; protocol in esi
; OUT: eax is socket num, -1 on error
;
;-----------------------------------------------
139,6 → 140,7
 
mov [eax + SOCKET.Domain], ecx
mov [eax + SOCKET.Type], edx
mov [eax + SOCKET.Protocol], esi
 
stdcall net_socket_addr_to_num, eax
DEBUGF 1,", socketnumber: %u\n", eax
154,7 → 156,6
;
; SOCKET_bind
;
;
; IN: socket number in ecx
; pointer to sockaddr struct in edx
; length of that struct in esi
184,6 → 185,7
jl s_error
 
mov bx, word [edx + 2]
rol bx,8 ;;;
DEBUGF 1,"local port: %u ",bx
test bx, bx
jnz .check_only
280,6 → 282,7
.udp:
 
mov bx , word [edx + 2]
rol bx, 8
mov word [eax + SOCKET.RemotePort], bx
 
DEBUGF 1,"remote port: %u ",bx
735,12 → 738,13
mov ecx, esi
mov esi, edx
mov edx, dword [eax + SOCKET.LocalPort] ; load local port and remote port at once
 
DEBUGF 1,"local port: %u, remote port:%u\n",[eax + SOCKET.LocalPort]:2, [eax + SOCKET.RemotePort]:2
bswap edx ;;;
rol edx, 16 ;;;
mov ebx, [eax + SOCKET.LocalIP]
mov eax, [eax + SOCKET.RemoteIP]
 
call UDP_create_Packet
call UDP_create_packet
 
mov [esp+32], eax
ret
765,7 → 769,7
add esi, ICMP_Packet.Data
mov ebx, [eax + SOCKET.LocalIP]
mov eax, [eax + SOCKET.RemoteIP]
call ICMP_create_Packet
call ICMP_create_packet
 
mov [esp+32], eax
ret
/kernel/branches/net/network/stack.inc
110,7 → 110,7
cmp [ETH_RUNNING], 0
je .exit
 
call ETH_Handler ; handle all queued ethernet packets
call ETH_handler ; handle all queued ethernet packets
call ETH_send_queued
 
; Test for 10ms tick, call tcp timer
188,6 → 188,13
align 4
sys_network:
 
cmp ebx, -1
jne @f
 
mov eax, [ETH_RUNNING]
jmp .return
 
@@:
cmp bh, MAX_NET_DEVICES ; Check if device number exists
jge .doesnt_exist
 
200,7 → 207,7
 
test bl, bl ; 0 = Get device type (ethernet/token ring/...)
jnz @f
 
; todo
xor eax, eax
jmp .return
 
/kernel/branches/net/network/tcp.inc
1,21 → 1,20
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2008. All rights reserved. ;;
;; Copyright (C) KolibriOS team 2004-2009. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;; TCP.INC ;;
;; ;;
;; TCP Processes for Menuet OS TCP/IP stack ;;
;; Part of the tcp/ip network stack for KolibriOS ;;
;; ;;
;; Copyright 2002 Mike Hibbett, mikeh@oceanfree.net ;;
;; Written by hidnplayr@kolibrios.org ;;
;; ;;
;; See file COPYING for details ;;
;; v0.6 : Added reset handling in the established state ;;
;; Added a timer per socket to allow delays when ;;
;; rx window gets below 1KB ;;
;; GNU GENERAL PUBLIC LICENSE ;;
;; Version 2, June 1991 ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
 
$Revision: 1019 $
 
 
44,6 → 43,8
TCP_RETRIES equ 5 ; Number of times to resend a Packet
TCP_TIMEOUT equ 10 ; resend if not replied to in x hs
 
TCP_QUEUE_SIZE equ 16
 
struct TCP_Packet
.SourcePort dw ?
.DestinationPort dw ?
59,17 → 60,59
.Data:
ends
 
align 4
uglobal
TCP_PACKETS_TX rd MAX_IP
TCP_PACKETS_RX rd MAX_IP
 
;***************************************************************************
; Function
TCP_IN_QUEUE rd 3*TCP_QUEUE_SIZE+3
TCP_OUT_QUEUE rd 3*TCP_QUEUE_SIZE+3
endg
 
 
 
 
 
;-----------------------------------------------------------------
;
; TCP_init
;
; This function resets all TCP variables
;
; IN: /
; OUT: /
;
;-----------------------------------------------------------------
 
align 4
TCP_init:
 
xor eax, eax
mov edi, TCP_PACKETS_TX
mov ecx, 2*MAX_IP
rep stosd
 
mov dword [TCP_IN_QUEUE], TCP_QUEUE_SIZE
mov dword [TCP_IN_QUEUE+4], TCP_IN_QUEUE + queue.data
mov dword [TCP_IN_QUEUE+8], TCP_IN_QUEUE + queue.data
 
mov dword [TCP_OUT_QUEUE], TCP_QUEUE_SIZE
mov dword [TCP_OUT_QUEUE+4], TCP_OUT_QUEUE + queue.data
mov dword [TCP_OUT_QUEUE+8], TCP_OUT_QUEUE + queue.data
 
ret
 
 
;-----------------------------------------------------------------
;
; tcp_tcb_handler
;
; Description
; Handles sockets in the timewait state, closing them
; when the TCB timer expires
;
;***************************************************************************
;-----------------------------------------------------------------
 
align 4
tcp_tcb_handler:
; scan through all the sockets, decrementing active timers
 
84,7 → 127,7
or ebx, ebx
jz .exit
 
DEBUGF 1, "K : %x-%x: %x-%x-%x-%u\n", [ebx + SOCKET.PID]:2, [ebx + SOCKET.Number]:2, [ebx + SOCKET.LocalPort]:4, [ebx + SOCKET.RemoteIP], [ebx + SOCKET.RemotePort]:4, [ebx + SOCKET.TCBState]
; DEBUGF 1, "K : %x-%x: %x-%x-%x-%u\n", [ebx + SOCKET.PID]:2, [ebx + SOCKET.Number]:2, [ebx + SOCKET.LocalPort]:4, [ebx + SOCKET.RemoteIP], [ebx + SOCKET.RemotePort]:4, [ebx + SOCKET.TCBState]
 
cmp [ebx + SOCKET.TCBTimer], 0
jne .decrement_tcb
124,7 → 167,8
;
;***************************************************************************
 
proc tcp_tx_handler stdcall
align 4
tcp_tx_handler:
; decrement all resend buffers timers. If they
; expire, queue them for sending, and restart the timer.
; If the retries counter reach 0, delete the entry
133,7 → 177,7
mov ecx, 0
 
.next_resendq:
cmp ecx, NUMRESENDENTRIES
; cmp ecx, NUMRESENDENTRIES
je .exit ; None left
cmp dword[esi + 4], 0
jne @f ; found one
162,9 → 206,9
@@: ; resend Packet
pushad
 
mov eax, EMPTY_QUEUE
call dequeue
cmp ax, NO_BUFFER
; mov eax, EMPTY_QUEUE
; call dequeue
; cmp ax, NO_BUFFER
jne .tth004z
 
; TODO - try again in 10ms.
179,21 → 223,21
 
.tth004z:
; we have a buffer # in ax
push eax ecx
mov ecx, IPBUFFSIZE
mul ecx
add eax, IPbuffs
; push eax ecx
; mov ecx, IPBUFFSIZE
; mul ecx
; add eax, IPbuffs
 
; we have the buffer address in eax
mov edi, eax
pop ecx
; Now get buffer location, and copy buffer across. argh! more copying,,
mov esi, resendBuffer
@@: add esi, IPBUFFSIZE
; mov esi, resendBuffer
; @@: add esi, IPBUFFSIZE
loop @b
 
; we have resend buffer location in esi
mov ecx, IPBUFFSIZE
; mov ecx, IPBUFFSIZE
 
; copy data across
push edi
202,15 → 246,15
pop edi
 
; queue Packet
mov eax, NET1OUT_QUEUE
mov edx, [IP_LIST]
cmp edx, [edi + IP_Packet.DestinationAddress]
jne .not_local
mov eax, IPIN_QUEUE
; mov eax, NET1OUT_QUEUE
; mov edx, [IP_LIST]
; cmp edx, [edi + IP_Packet.DestinationAddress]
; jne .not_local
; mov eax, IPIN_QUEUE
 
.not_local:
pop ebx
call queue
; call queue
 
.tth005:
popad
221,36 → 265,33
 
.exit:
ret
endp
 
 
;***************************************************************************
; Function
; tcp_rx
 
;-----------------------------------------------------------------
;
; Description
; TCP protocol handler
; This is a kernel function, called by ip_rx
; IP buffer address given in edx
; IP buffer number in eax
; Free up (or re-use) IP buffer when finished
; TCP_Handler:
;
;***************************************************************************
; Called by IPv4_handler,
; this procedure will inject the tcp data diagrams in the application sockets.
;
; IN: Pointer to buffer in [esp]
; size of buffer in [esp+4]
; pointer to device struct in ebx
; TCP Packet size in ecx
; pointer to TCP Packet data in edx
; SourceAddres in esi
; OUT: /
;
;-----------------------------------------------------------------
 
proc tcp_rx stdcall uses ebx
; The process is as follows.
; Look for a socket with matching remote IP, remote port, local port
; if not found, then
; look for remote IP + local port match ( where sockets remote port = 0)
; if not found, then
; look for a socket where local socket port == IP Packets remote port
; where sockets remote port, remote IP = 0
; discard if not found
; Call sockets tcbStateMachine, with pointer to Packet.
; the state machine will not delete the Packet, so do that here.
TCP_Handler :
 
push eax
 
DEBUGF 1,"TCP_Handler\n"
 
jmp .exit ;;;;
 
; Look for a socket where
; IP Packet TCP Destination Port = local Port
; IP Packet SA = Remote IP
265,19 → 306,19
 
; DEBUGF 1, "K : tcp_rx - 1.dport: %x - %x\n", [edx + 20 + TCP_Packet.DestinationPort]:4, [ebx + SOCKET.LocalPort]:4
 
mov ax, [edx + 20 + TCP_Packet.DestinationPort] ; get the dest. port from the TCP hdr
mov ax, [edx + TCP_Packet.DestinationPort] ; get the dest. port from the TCP hdr
cmp [ebx + SOCKET.LocalPort], ax ; get the dest. port from the TCP hdr
jne .next_socket.1 ; different - try next socket
 
; DEBUGF 1, "K : tcp_rx - 1.addr: %x - %x\n", [edx + IP_Packet.SourceAddress], [ebx + SOCKET.RemoteIP]
 
mov eax, [edx + IP_Packet.SourceAddress] ; get the source IP Addr from the IP hdr
mov eax, esi ;[edx + IP_Packet.SourceAddress] ; get the source IP Addr from the IP hdr
cmp [ebx + SOCKET.RemoteIP], eax ; compare with socket's remote IP
jne .next_socket.1 ; different - try next socket
 
; DEBUGF 1, "K : tcp_rx - 1.sport: %x - %x\n", [edx + 20 + TCP_Packet.SourcePort]:4, [ebx + SOCKET.RemotePort]:4
 
mov ax, [edx + 20 + TCP_Packet.SourcePort] ; get the source port from the TCP hdr
mov ax, [edx + TCP_Packet.SourcePort] ; get the source port from the TCP hdr
cmp [ebx + SOCKET.RemotePort], ax ; compare with socket's remote port
jne .next_socket.1 ; different - try next socket
 
301,14 → 342,14
 
; DEBUGF 1, "K : tcp_rx - 2.dport: %x - %x\n", [edx + 20 + TCP_Packet.DestinationPort]:4, [ebx + SOCKET.LocalPort]:4
 
mov ax, [edx + 20 + TCP_Packet.DestinationPort] ; get the dest. port from the TCP hdr
mov ax, [edx + TCP_Packet.DestinationPort] ; get the dest. port from the TCP hdr
cmp [ebx + SOCKET.LocalPort], ax ; compare with socket's local port
jne .next_socket.2 ; different - try next socket
 
; DEBUGF 1, "K : tcp_rx - 2.addr: %x - %x\n", [edx + IP_Packet.SourceAddress], [ebx + SOCKET.RemoteIP]
 
mov eax, [edx + IP_Packet.SourceAddress] ; get the source IP Addr from the IP hdr
cmp [ebx + SOCKET.RemoteIP], eax ; compare with socket's remote IP
; mov eax, esi ;[edx + IP_Packet.SourceAddress] ; get the source IP Addr from the IP hdr
cmp [ebx + SOCKET.RemoteIP], esi ; compare with socket's remote IP
jne .next_socket.2 ; different - try next socket
 
; DEBUGF 1, "K : tcp_rx - 2.sport: 0000 - %x\n", [ebx + SOCKET.RemotePort]:4
336,7 → 377,7
 
; DEBUGF 1, "K : tcp_rx - 3.dport: %x - %x\n", [edx + 20 + TCP_Packet.DestinationPort]:4, [ebx + SOCKET.LocalPort]:4
 
mov ax, [edx + 20 + TCP_Packet.DestinationPort] ; get destination port from the TCP hdr
mov ax, [edx + TCP_Packet.DestinationPort] ; get destination port from the TCP hdr
cmp [ebx + SOCKET.LocalPort], ax ; compare with socket's local port
jne .next_socket.3 ; different - try next socket
 
358,9 → 399,9
; If we got here, we need to reject the Packet
 
DEBUGF 1, "K : tcp_rx - dumped\n"
DEBUGF 1, "K : --------: %x-%x-%x (flags: %x)\n", [edx + 20 + TCP_Packet.DestinationPort]:4, [edx + IP_Packet.SourceAddress], [edx + 20 + TCP_Packet.SourcePort]:4, [edx + 20 + TCP_Packet.Flags]:2
; DEBUGF 1, "K : --------: %x-%x-%x (flags: %x)\n", [edx + 20 + TCP_Packet.DestinationPort]:4, [edx + IP_Packet.SourceAddress], [edx + 20 + TCP_Packet.SourcePort]:4, [edx + 20 + TCP_Packet.Flags]:2
 
inc [dumped_rx_count]
; inc [dumped_rx_count]
jmp .exit
 
.change_state:
373,12 → 414,27
stdcall tcpStateMachine, ebx
 
.exit:
pop eax
call freeBuff
 
call kernel_free
add esp, 4 ; pop (balance stack)
 
ret
endp
 
 
 
;-----------------------------------------------------------------
;
; IN: eax = dest ip
; ebx = source ip
; ecx = data length
; edx = remote port shl 16 + local port
; esi = data offset
;
;-----------------------------------------------------------------
 
TCP_create_Packet:
 
DEBUGF 1,"Create TCP Packet\n"
;***************************************************************************
; Function
; buildTCPPacket
394,30 → 450,31
;
;***************************************************************************
 
proc build_tcp_Packet stdcall, sockAddr:DWORD
push ecx ; Save data length
 
; convert buffer pointer eax to the absolute address
mov ecx, IPBUFFSIZE
mul ecx
add eax, IPbuffs
add ecx, UDP_Packet.Data
mov di , IP_PROTO_UDP
 
mov edx, eax
; dx = fragment id
 
mov [edx + 20 + TCP_Packet.Flags], bl ; TCP flags
call IPv4_create_Packet ; TODO: figure out a way to choose between IPv4 and IPv6
cmp edi, -1
je .exit
 
mov ebx, [sockAddr]
mov [edi + TCP_Packet.Flags], bl ; TCP flags
 
; mov ebx, [sockAddr];---------------------------------------------------------- eof
 
; So, ebx holds the socket ptr, edx holds the IPbuffer ptr
 
; Fill in the IP header ( some data is in the socket descriptor)
mov eax, [ebx + SOCKET.LocalIP]
mov [edx + IP_Packet.SourceAddress], eax
; mov [edx + IP_Packet.SourceAddress], eax
mov eax, [ebx + SOCKET.RemoteIP]
mov [edx + IP_Packet.DestinationAddress], eax
; mov [edx + IP_Packet.DestinationAddress], eax
 
mov [edx + IP_Packet.VersionAndIHL], 0x45
mov [edx + IP_Packet.TypeOfService], 0
; mov [edx + IP_Packet.VersionAndIHL], 0x45
; mov [edx + IP_Packet.TypeOfService], 0
 
pop eax ; Get the TCP data length
push eax
424,14 → 481,14
 
add eax, 20 + 20 ; add IP header and TCP header lengths
rol ax, 8
mov [edx + IP_Packet.TotalLength], ax
mov [edx + IP_Packet.Identification], 0
mov [edx + IP_Packet.FlagsAndFragmentOffset], 0x0040
mov [edx + IP_Packet.TimeToLive], 0x20
mov [edx + IP_Packet.Protocol], PROTOCOL_TCP
; mov [edx + IP_Packet.TotalLength], ax
; mov [edx + IP_Packet.Identification], 0
; mov [edx + IP_Packet.FlagsAndFragmentOffset], 0x0040
; mov [edx + IP_Packet.TimeToLive], 0x20
; mov [edx + IP_Packet.Protocol], PROTOCOL_TCP
 
; Checksum left unfilled
mov [edx + IP_Packet.HeaderChecksum], 0
; mov [edx + IP_Packet.HeaderChecksum], 0
 
; Fill in the TCP header (some data is in the socket descriptor)
mov ax, [ebx + SOCKET.LocalPort]
475,54 → 532,64
@@: ; we have edx as IPbuffer ptr.
; Fill in the TCP checksum
; First, fill in pseudoheader
mov eax, [edx + IP_Packet.SourceAddress]
mov [pseudoHeader], eax
mov eax, [edx + IP_Packet.DestinationAddress]
mov [pseudoHeader + 4], eax
mov word[pseudoHeader + 8], PROTOCOL_TCP shl 8 + 0
add ebx, 20
mov [pseudoHeader + 10], bh
mov [pseudoHeader + 11], bl
; mov eax, [edx + IP_Packet.SourceAddress]
; mov [pseudoHeader], eax
; mov eax, [edx + IP_Packet.DestinationAddress]
; mov [pseudoHeader + 4], eax
; mov word[pseudoHeader + 8], PROTOCOL_TCP shl 8 + 0
; add ebx, 20
; mov [pseudoHeader + 10], bh
; mov [pseudoHeader + 11], bl
;
; mov eax, pseudoHeader
; mov [checkAdd1], eax
; mov word[checkSize1], 12
; mov eax, edx
; add eax, 20
; mov [checkAdd2], eax
; mov eax, ebx
; mov [checkSize2], ax
;
; call checksum
 
mov eax, pseudoHeader
mov [checkAdd1], eax
mov word[checkSize1], 12
mov eax, edx
add eax, 20
mov [checkAdd2], eax
mov eax, ebx
mov [checkSize2], ax
 
call checksum
 
; store it in the TCP checksum ( in the correct order! )
mov ax, [checkResult]
rol ax, 8
mov [edx + 20 + TCP_Packet.Checksum], ax
; mov ax, [checkResult]
; rol ax, 8
; mov [edx + 20 + TCP_Packet.Checksum], ax
 
; Fill in the IP header checksum
movzx eax, byte [edx + IP_Packet.VersionAndIHL] ; Calculate Header length by using IHL field
and eax, 0x0000000F ;
shl eax, 2 ;
 
; movzx eax, byte [edx + IP_Packet.VersionAndIHL] ; Calculate Header length by using IHL field
; and eax, 0x0000000F ;
; shl eax, 2 ;
;
stdcall checksum_jb, edx, eax ; buf_ptr, buf_size
rol ax, 8
mov [edx + IP_Packet.HeaderChecksum], ax
; mov [edx + IP_Packet.HeaderChecksum], ax
 
 
.exit:
 
call kernel_free
add esp, 4 ; pop (balance stack)
 
ret
endp
;endp
 
 
; Increments the 32 bit value pointed to by esi in internet order
proc inc_inet_esi stdcall
push eax
mov eax, [esi]
bswap eax
inc eax
bswap eax
mov [esi], eax
pop eax
ret
; push eax
; mov eax, [esi]
; bswap eax
; inc eax
; bswap eax
; mov [esi], eax
; pop eax
; ret
inc byte[esi+0]
adc byte[esi+1],0
adc byte[esi+2],0
adc byte[esi+3],0
endp
 
 
591,7 → 658,7
xor ecx, ecx
 
.next_resendq:
cmp ecx, NUMRESENDENTRIES
; cmp ecx, NUMRESENDENTRIES
je .call_handler ; None left
cmp [esi + 4], eax
je @f ; found one
606,8 → 673,8
 
push ecx
; Now get buffer location, and copy buffer across. argh! more copying,,
imul edi, ecx, IPBUFFSIZE
add edi, resendBuffer
; imul edi, ecx, IPBUFFSIZE
; add edi, resendBuffer
 
; we have dest buffer location in edi. incoming Packet in edx.
; Get this Packets sequence number
668,41 → 735,41
; We have a SYN. update the socket with this IP Packets details,
; And send a response
 
mov eax, [edx + IP_Packet.SourceAddress]
mov [ebx + SOCKET.RemoteIP], eax
mov ax, [edx + 20 + TCP_Packet.SourcePort]
mov [ebx + SOCKET.RemotePort], ax
mov eax, [edx + 20 + TCP_Packet.SequenceNumber]
mov [ebx + SOCKET.IRS], eax
mov [ebx + SOCKET.RCV_NXT], eax
lea esi, [ebx + SOCKET.RCV_NXT]
call inc_inet_esi ; RCV.NXT
mov eax, [ebx + SOCKET.ISS]
mov [ebx + SOCKET.SND_NXT], eax
 
; mov eax, [edx + IP_Packet.SourceAddress]
; mov [ebx + SOCKET.RemoteIP], eax
; mov ax, [edx + 20 + TCP_Packet.SourcePort]
; mov [ebx + SOCKET.RemotePort], ax
; mov eax, [edx + 20 + TCP_Packet.SequenceNumber]
; mov [ebx + SOCKET.IRS], eax
; mov [ebx + SOCKET.RCV_NXT], eax
; lea esi, [ebx + SOCKET.RCV_NXT]
; call inc_inet_esi ; RCV.NXT
; mov eax, [ebx + SOCKET.ISS]
; mov [ebx + SOCKET.SND_NXT], eax
;
; Now construct the response, and queue for sending by IP
mov eax, EMPTY_QUEUE
call dequeue
cmp ax, NO_BUFFER
je .exit
; mov eax, EMPTY_QUEUE
; call dequeue
; cmp ax, NO_BUFFER
; je .exit
 
push eax
mov bl, TH_SYN + TH_ACK
xor ecx, ecx
xor esi, esi
stdcall build_tcp_Packet, [sockAddr]
; stdcall build_tcp_Packet, [sockAddr]
 
mov eax, NET1OUT_QUEUE
; mov eax, NET1OUT_QUEUE
;;; mov edx, [stack_ip]
mov ecx, [sockAddr]
cmp edx, [ecx + SOCKET.RemoteIP]
jne .not_local
mov eax, IPIN_QUEUE
; mov eax, IPIN_QUEUE
 
.not_local:
; Send it.
pop ebx
call queue
;;; call queue
 
mov esi, [sockAddr]
mov [esi + SOCKET.TCBState], TCB_SYN_RECEIVED
747,9 → 814,9
 
; Send an ACK
; Now construct the response, and queue for sending by IP
mov eax, EMPTY_QUEUE
call dequeue
cmp ax, NO_BUFFER
; mov eax, EMPTY_QUEUE
; call dequeue
; cmp ax, NO_BUFFER
pop ebx
je .exit
 
757,19 → 824,19
 
xor ecx, ecx
xor esi, esi
stdcall build_tcp_Packet, [sockAddr]
; stdcall build_tcp_Packet, [sockAddr]
 
mov eax, NET1OUT_QUEUE
; mov eax, NET1OUT_QUEUE
;;; mov edx, [stack_ip]
mov ecx, [sockAddr]
cmp edx, [ecx + SOCKET.RemoteIP]
jne .not_local
mov eax, IPIN_QUEUE
; mov ecx, [sockAddr]
; cmp edx, [ecx + SOCKET.RemoteIP]
; jne .not_local
; mov eax, IPIN_QUEUE
 
.not_local:
; Send it.
pop ebx
call queue
;;; call queue
 
.exit:
ret
822,13 → 889,13
mov ecx, 0
 
.next_resendq:
cmp ecx, NUMRESENDENTRIES
je .last_resendq ; None left
cmp [esi + 4], eax
je @f ; found one
inc ecx
add esi, 8
jmp .next_resendq
; cmp ecx, NUMRESENDENTRIES
; je .last_resendq ; None left
; cmp [esi + 4], eax
; je @f ; found one
; inc ecx
; add esi, 8
; jmp .next_resendq
 
@@: mov dword[esi + 4], 0
inc ecx
881,7 → 948,7
 
 
; Read the data bytes, store in socket buffer
movzx ecx, [edx + IP_Packet.TotalLength]
; movzx ecx, [edx + IP_Packet.TotalLength]
xchg cl, ch
sub ecx, 40 ; Discard 40 bytes of header
ja .data ; Read data, if any
943,9 → 1010,9
.ack:
; Send an ACK
; Now construct the response, and queue for sending by IP
mov eax, EMPTY_QUEUE
call dequeue
cmp ax, NO_BUFFER
; mov eax, EMPTY_QUEUE
; call dequeue
; cmp ax, NO_BUFFER
je .exit
 
push eax
953,20 → 1020,20
mov bl, TH_ACK
xor ecx, ecx
xor esi, esi
stdcall build_tcp_Packet, [sockAddr]
; stdcall build_tcp_Packet, [sockAddr]
 
mov eax, NET1OUT_QUEUE
; mov eax, NET1OUT_QUEUE
 
;;; mov edx, [stack_ip]
mov ecx, [sockAddr]
cmp edx, [ecx + SOCKET.RemoteIP]
jne .not_local
mov eax, IPIN_QUEUE
; mov ecx, [sockAddr]
; cmp edx, [ecx + SOCKET.RemoteIP]
; jne .not_local
; mov eax, IPIN_QUEUE
 
.not_local:
; Send it.
pop ebx
call queue
;;; call queue
 
.exit:
ret
1000,9 → 1067,9
call inc_inet_esi
 
; Send an ACK
mov eax, EMPTY_QUEUE
call dequeue
cmp ax, NO_BUFFER
; mov eax, EMPTY_QUEUE
; call dequeue
; cmp ax, NO_BUFFER
je .exit
 
push eax
1010,19 → 1077,19
mov bl, TH_ACK
xor ecx, ecx
xor esi, esi
stdcall build_tcp_Packet, [sockAddr]
; stdcall build_tcp_Packet, [sockAddr]
 
mov eax, NET1OUT_QUEUE
; mov eax, NET1OUT_QUEUE
;;; mov edx, [stack_ip]
mov ecx, [sockAddr]
cmp edx, [ecx + SOCKET.RemoteIP]
jne .not_local
mov eax, IPIN_QUEUE
; mov ecx, [sockAddr]
; cmp edx, [ecx + SOCKET.RemoteIP]
; jne .not_local
; mov eax, IPIN_QUEUE
 
.not_local:
; Send it.
pop ebx
call queue
;;; call queue
 
.exit:
ret
1040,10 → 1107,10
call inc_inet_esi
 
; Send an ACK
mov eax, EMPTY_QUEUE
call dequeue
cmp ax, NO_BUFFER
je .exit
; mov eax, EMPTY_QUEUE
; call dequeue
;; cmp ax, NO_BUFFER
; je .exit
 
push eax
 
1050,19 → 1117,19
mov bl, TH_ACK
xor ecx, ecx
xor esi, esi
stdcall build_tcp_Packet, [sockAddr]
; stdcall build_tcp_Packet, [sockAddr]
 
mov eax, NET1OUT_QUEUE
; mov eax, NET1OUT_QUEUE
;;; mov edx, [stack_ip]
mov ecx, [sockAddr]
cmp edx, [ecx + SOCKET.RemoteIP]
jne .not_local
mov eax, IPIN_QUEUE
; mov eax, IPIN_QUEUE
 
.not_local:
; Send it.
pop ebx
call queue
;;; call queue
 
.exit:
ret
1119,8 → 1186,8
; @param EDX is pointer to application data buffer
; @return 0 (sent successfully) or -1 (error) in EAX
;;
proc socket_write_tcp stdcall
local sockAddr dd ?
;proc socket_write_tcp stdcall
;local sockAddr dd ?
 
; DEBUGF 1, "socket_write_tcp(0x%x)\n", ebx
stdcall net_socket_num_to_addr, ebx
1128,16 → 1195,16
jz .error
 
mov ebx, eax
mov [sockAddr], ebx
; mov [sockAddr], ebx
 
; If the sockets window timer is nonzero, do not queue Packet
cmp [ebx + SOCKET.wndsizeTimer], 0
jne .error
 
mov eax, EMPTY_QUEUE
call dequeue
cmp ax, NO_BUFFER
je .error
; mov eax, EMPTY_QUEUE
; call dequeue
; cmp ax, NO_BUFFER
; je .error
 
push eax
 
1152,7 → 1219,7
 
push ecx
mov bl, TH_ACK
stdcall build_tcp_Packet, [sockAddr]
; stdcall build_tcp_Packet, [sockAddr]
pop ecx
 
; Check destination IP address.
1161,24 → 1228,24
pop ebx
push ecx
 
mov eax, NET1OUT_QUEUE
; mov eax, NET1OUT_QUEUE
;;; TODO: get device id in edx
xor edx, edx
 
shl edx, 2
mov edx, [IP_LIST+edx]
mov ecx, [sockAddr]
cmp edx, [ecx + SOCKET.RemoteIP]
jne .not_local
mov eax, IPIN_QUEUE
; mov ecx, [sockAddr]
; cmp edx, [ecx + SOCKET.RemoteIP]
; jne .not_local
; mov eax, IPIN_QUEUE
 
.not_local:
pop ecx
push ebx ; save ipbuffer number
 
call queue
;;;; call queue
 
mov esi, [sockAddr]
; mov esi, [sockAddr]
 
; increament SND.NXT in socket
; Amount to increment by is in ecx
1193,7 → 1260,7
mov ecx, 0
 
.next_resendq:
cmp ecx, NUMRESENDENTRIES
; cmp ecx, NUMRESENDENTRIES
je .exit ; None found
cmp dword[esi + 4], 0
je @f ; found one
1211,7 → 1278,7
; retry time
; fill IP buffer associated with this descriptor
 
stdcall net_socket_addr_to_num, [sockAddr]
; stdcall net_socket_addr_to_num, [sockAddr]
mov [esi + 4], eax
mov byte[esi + 1], TCP_RETRIES
mov word[esi + 2], TCP_TIMEOUT
1218,21 → 1285,21
 
inc ecx
; Now get buffer location, and copy buffer across. argh! more copying,,
mov edi, resendBuffer - IPBUFFSIZE
; mov edi, resendBuffer - IPBUFFSIZE
 
@@: add edi, IPBUFFSIZE
; @@: add edi, IPBUFFSIZE
loop @b
 
; we have dest buffer location in edi
pop eax
; convert source buffer pointer eax to the absolute address
mov ecx, IPBUFFSIZE
mul ecx
add eax, IPbuffs
mov esi, eax
; mov ecx, IPBUFFSIZE
; mul ecx
; add eax, IPbuffs
; mov esi, eax
 
; do copy
mov ecx, IPBUFFSIZE
; mov ecx, IPBUFFSIZE
; cld
rep movsb
 
1243,7 → 1310,7
.error:
or eax, -1
ret
endp
;endp
 
 
 
1262,10 → 1329,10
 
checksum:
pusha
mov eax, [checkAdd1]
; mov eax, [checkAdd1]
xor edx, edx ; edx is the accumulative checksum
xor ebx, ebx
mov cx, [checkSize1]
; mov cx, [checkSize1]
shr cx, 1
jz cs1_1
 
1279,7 → 1346,7
loopw cs1
 
cs1_1:
and word [checkSize1], 0x01
; and word [checkSize1], 0x01
jz cs_test2
 
mov bh, [eax]
1288,11 → 1355,11
add edx, ebx
 
cs_test2:
mov cx, [checkSize2]
; mov cx, [checkSize2]
cmp cx, 0
jz cs_exit ; Finished if no 2nd buffer
 
mov eax, [checkAdd2]
; mov eax, [checkAdd2]
 
shr cx, 1
jz cs2_1
1307,7 → 1374,7
loopw cs2
 
cs2_1:
and word [checkSize2], 0x01
; and word [checkSize2], 0x01
jz cs_exit
 
mov bh, [eax]
1326,21 → 1393,7
add edx, eax
not dx
 
mov [checkResult], dx
; mov [checkResult], dx
popa
ret
 
 
 
 
 
TCP_HANDLER:
;;; TODO: write code here
 
call kernel_free
add esp, 4 ; pop (balance stack)
 
ret
 
 
 
/kernel/branches/net/network/udp.inc
1,6 → 1,6
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2008. All rights reserved. ;;
;; Copyright (C) KolibriOS team 2004-2009. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;; UDP.INC ;;
73,7 → 73,7
;
;-----------------------------------------------------------------
 
UDP_Handler:
UDP_handler:
 
DEBUGF 1,"UDP_Handler\n"
; TODO: First validate the header & checksum. Discard buffer if error
110,7 → 110,6
@@:
DEBUGF 1,"Found valid UDP packet for socket %x\n", esi
 
 
; sub ecx, UDP_Packet.Data ; get # of bytes in ecx
; mov eax, ecx
 
199,12 → 198,12
; IN: eax = dest ip
; ebx = source ip
; ecx = data length
; edx = remote port shl 16 + local port
; edx = remote port shl 16 + local port (both in INET order)
; esi = data offset
;
;-----------------------------------------------------------------
 
UDP_create_Packet:
UDP_create_packet:
 
DEBUGF 1,"Create UDP Packet\n"
 
215,13 → 214,13
 
; dx = fragment id
 
call IPv4_create_Packet ; TODO: figure out a way to choose between IPv4 and IPv6
call IPv4_create_packet ; TODO: figure out a way to choose between IPv4 and IPv6
cmp edi, -1
je .exit
 
sub ecx , UDP_Packet.Data
mov byte[edi + UDP_Packet.Length], ch
mov byte[edi + UDP_Packet.Length+1], cl
sub ecx , UDP_Packet.Data
 
pop esi
push edi
235,8 → 234,8
pop edi
 
pop ecx
bswap ecx ; convert little endian - big endian
rol ecx, 16 ;
; bswap ecx ; convert little endian - big endian
; rol ecx, 16 ;
mov dword [edi + UDP_Packet.SourcePort], ecx ; notice: we write both port's at once