From 602924a5b5f119df3ab5b0376ff9bd45415d156f Mon Sep 17 00:00:00 2001 From: hidnplayr Date: Mon, 5 Oct 2009 20:47:27 +0000 Subject: [PATCH] compile netcfg on unix fixed bug in netcfg created in last revision netcfg gives error msg when driver is not loaded zeroconfig now works with latest version of libini also fixed use of static and link-local ip in zeroconfig initial IPv4 variables are now 0.0.0.0 instead of 255.255.255.255 created kernel function that shows number of active network devices fixed the use of temp mac variable in IPV4.inc (variable is now in stack) rewrite of ARP code, needs full testing/debugging (new application needed: ARP manager) port numbers are now in INET byte order, as is in posix standards git-svn-id: svn://kolibrios.org@1196 a494cfbc-eb01-0410-851d-a64ba20cac60 --- .../net/applications/netcfg/netcfg.asm | 60 +- .../net/applications/zeroconf/zeroconf.asm | 25 +- kernel/branches/net/drivers/pcnet32.asm | 1637 +++++++++++++++++ kernel/branches/net/kernel.asm | 2 +- kernel/branches/net/network/ARP.inc | 603 +++--- kernel/branches/net/network/IPv4.inc | 54 +- kernel/branches/net/network/ethernet.inc | 20 +- kernel/branches/net/network/icmp.inc | 12 +- kernel/branches/net/network/queue.inc | 2 +- kernel/branches/net/network/socket.inc | 42 +- kernel/branches/net/network/stack.inc | 11 +- kernel/branches/net/network/tcp.inc | 553 +++--- kernel/branches/net/network/udp.inc | 17 +- 13 files changed, 2327 insertions(+), 711 deletions(-) create mode 100644 kernel/branches/net/drivers/pcnet32.asm diff --git a/kernel/branches/net/applications/netcfg/netcfg.asm b/kernel/branches/net/applications/netcfg/netcfg.asm index 2e65397e48..08546b2d0e 100644 --- a/kernel/branches/net/applications/netcfg/netcfg.asm +++ b/kernel/branches/net/applications/netcfg/netcfg.asm @@ -38,8 +38,8 @@ button: ; button jne @f mcall -1 ; close this program @@: - cmp eax,0x0000fe00 - jg @f + cmp eax,0x0000ff00 + jg load_drv cmp ah, 4 je hook @@ -51,25 +51,17 @@ button: ; button je unload jmp still - @@: + + +load_drv: 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 - mov bl , 6 ; get a dword - mov bh , ah ; bus - mov ch , al ; dev + mov bh , ah ; bus + mov ch , al ; dev mov cl , 0 ; offset to device/vendor id - mcall 62 ; get ID's + mcall 62 ; get ID's mov word [PCI_Vendor], ax shr eax, 16 @@ -77,11 +69,19 @@ load_drv: call get_drv_ptr mov ecx, eax - mcall 68, 16 + mcall 68, 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] @@ -97,30 +97,28 @@ hook: mov [IOCTL.out_size], 0 mov [IOCTL.output], 0 - mcall 68, 17, IOCTL + mcall 68, 17, IOCTL 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,8 +126,9 @@ draw_window: 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 @@ -144,7 +143,7 @@ draw_window: jmp .done -.nonefound : +.nonefound: mcall 4, 20 shl 16 + 30, 1 shl 31 + 0x00ff0000 , nonefound .done: mcall 12, 2 ; end of draw @@ -379,8 +378,8 @@ get_drv_ptr: driverfound: ret -include 'VENDORS.INC' -include 'DRIVERS.INC' +include 'vendors.inc' +include 'drivers.inc' ;------------------------------------------------------------------ ; DATA AREA DATA @@ -404,6 +403,7 @@ btn_stop db 'Stop device',0 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 diff --git a/kernel/branches/net/applications/zeroconf/zeroconf.asm b/kernel/branches/net/applications/zeroconf/zeroconf.asm index 3efbac2f34..26f314d627 100644 --- a/kernel/branches/net/applications/zeroconf/zeroconf.asm +++ b/kernel/branches/net/applications/zeroconf/zeroconf.asm @@ -42,14 +42,11 @@ RATE_LIMIT_INTERVAL equ 60 ; seconds (delay between successive attempts) 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 @@ START: ; start of execution 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 @@ link_local: 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 @@ library \ libini,'libini.obj' import libini, \ - ini.get_str,'ini.get_str' + ini.get_str,'ini_get_str' include_debug_strings @@ -575,7 +572,7 @@ str_type db 'type',0 sockaddr1: dw AF_INET4 - dw 68 ; local port + dw 68 shl 8 ; local port dd 0 ; local IP rb 10 @@ -584,7 +581,7 @@ sockaddr1: sockaddr2: dw AF_INET4 - dw 67 ; destination port + dw 67 shl 8 ; destination port dd -1 ; destination IP rb 10 diff --git a/kernel/branches/net/drivers/pcnet32.asm b/kernel/branches/net/drivers/pcnet32.asm new file mode 100644 index 0000000000..243e976cb6 --- /dev/null +++ b/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 diff --git a/kernel/branches/net/kernel.asm b/kernel/branches/net/kernel.asm index 6f9ce875a5..d15e2cf3d0 100644 --- a/kernel/branches/net/kernel.asm +++ b/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) diff --git a/kernel/branches/net/network/ARP.inc b/kernel/branches/net/network/ARP.inc index 5249654040..85a99d7015 100644 --- a/kernel/branches/net/network/ARP.inc +++ b/kernel/branches/net/network/ARP.inc @@ -1,22 +1,21 @@ -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; ;; -;; Copyright (C) KolibriOS team 2004-2008. All rights reserved. ;; -;; Distributed under terms of the GNU General Public License ;; -;; ;; -;; ARP.INC ;; -;; ;; -;; Address Resolution Protocol ;; -;; ;; -;; 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 ;; -;; ;; -;; Changes history: ;; -;; 22.09.2003 - [Mike Hibbett] : mikeh@oceanfree.net ;; -;; 11.11.2006 - [Johnny_B] and [smb] ;; -;; ;; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; Copyright (C) KolibriOS team 2004-2009. All rights reserved. ;; +;; Distributed under terms of the GNU General Public License ;; +;; ;; +;; ARP.INC ;; +;; ;; +;; Part of the tcp/ip network stack for KolibriOS ;; +;; ;; +;; Based on the work of [Johnny_B] and [smb] ;; +;; ;; +;; Written by hidnplayr@kolibrios.org ;; +;; ;; +;; GNU GENERAL PUBLIC LICENSE ;; +;; Version 2, June 1991 ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + $Revision: 983 $ @@ -26,6 +25,9 @@ ARP_VALID_MAPPING equ 1 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 @@ endg +;----------------------------------------------------------------- +; +; ARP_init +; +; This function resets all ARP variables +; +; IN: / +; OUT: / +; +;----------------------------------------------------------------- +align 4 ARP_init: xor eax, eax @@ -93,175 +106,23 @@ ARP_init: 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 - -;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 +; 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' +; +;----------------------------------------------------------------- align 4 -proc arp_table_manager stdcall uses ebx esi edi ecx edx, Opcode:DWORD,Index:DWORD,Extra:DWORD - - mov ebx, ARPTable ;ARPTable base - mov ecx, dword[NumARP] ;ARP-entries counter - - 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 +ARP_IP_to_MAC: + DEBUGF 1,"ARP_IP_to_MAC\n" ; first, check destination IP to see if it is on 'this' network. ; The test is: @@ -270,184 +131,130 @@ proc arp_table_manager stdcall uses ebx esi edi ecx edx, Opcode:DWORD,Index:DWOR ; 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 - @@: + mov eax, [GATEWAY_LIST+edx] + 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 + ret + + .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 - - DEBUGF 1,"Create ARP request\n" +; OUT: / +; +;--------------------------------------------------------------------------- - stdcall kernel_alloc, 60 ; minimum eth packet size - test eax, eax - jz .exit +align 4 +ARP_create_request: - mov ebx, eax + DEBUGF 1,"Create ARP Packet\n" - 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 + call IPv4_dest_to_dev - DEBUGF 1,"1" + push eax ; DestIP + mov eax, [IP_LIST+4*edi] ; senderIP + push eax - cld - mov esi, [SenderMAC_ptr] - lea edi, [ebx + ETH_FRAME.Data + ARP_Packet.SenderMAC] ;Our MAC-addr - movsd - movsw + 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 - DEBUGF 1,"2" + 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 - mov esi, [SenderIP_ptr] - mov [ebx + ETH_FRAME.Data + ARP_Packet.SenderIP], esi ;Our IP-addr -; movsd + add edi, ARP_Packet.SenderMAC ; sendermac + lea esi, [edx + ETH_DEVICE.mac] ; + movsw ; + movsd ; - DEBUGF 1,"3" + pop eax + stosd ; - lea edi, [ebx + ETH_FRAME.Data + ARP_Packet.TargetMAC] ; Required MAC-addr - xor eax, eax - stosd - stosw + xor eax, eax ; destmac + movsw ; + movsw ; - DEBUGF 1,"4" + pop eax + movsd ; - lea edi, [ebx + ETH_FRAME.DstMAC] - stosd - stosw + DEBUGF 1,"ARP Packet for device %x created successfully\n", edx - DEBUGF 1,"5" + call esi - mov esi, [TargetIP] - mov dword [ebx + ETH_FRAME.Data + ARP_Packet.TargetIP], esi ;Required IP-addr(we get it as function parameter) - - - 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" - ret -endp + inc [ARP_PACKETS_TX+4*edi] + ret + .exit: + add esp, 8 + DEBUGF 1,"Create ARP Packet - failed\n" + mov eax, -1 + ret @@ -512,6 +319,81 @@ ARP_decrease_entry_ttls: 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 + + ;--------------------------------------------------------------------------- ; @@ -537,13 +419,12 @@ ARP_del_entry: cld rep movsw - dec dword[NumARP] ;decrease arp-entries counter + dec [NumARP] ;decrease arp-entries counter ret - ;----------------------------------------------------- ; ; ARP_Handler: @@ -557,22 +438,53 @@ ARP_del_entry: ; 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 @@ ARP_Handler: 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,12 +533,12 @@ ARP_Handler: lea esi, [edx + ARP_Packet.SenderMAC] movsd movsw - mov ax , ETHER_ARP - stosw +; mov ax , ETHER_ARP +; stosw jmp ETH_Sender ; And send it! - .exit: + .exit: call kernel_free add esp, 4 ; pop (balance stack) @@ -672,7 +582,6 @@ ARP_API: jz .remove ; 5 dec bl - .error: mov eax, -1 ret @@ -697,9 +606,11 @@ ARP_API: .write: ; TODO: write code + ; call ARP_write_entry ret .remove: - ; TODO: write code + mov esi, eax + call ARP_del_entry ret diff --git a/kernel/branches/net/network/IPv4.inc b/kernel/branches/net/network/IPv4.inc index 5ae569ccf0..ca945d5eea 100644 --- a/kernel/branches/net/network/IPv4.inc +++ b/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 @@ IPv4_init: 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 @@ IPv4_init: ;----------------------------------------------------------------- align 4 -IPv4_Handler: +IPv4_handler: DEBUGF 1,"IP_Handler - start\n" mov cx , [edx + IPv4_Packet.HeaderChecksum] @@ -186,13 +188,13 @@ IPv4_Handler: 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 @@ IPv4_Handler: 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 @@ IPv4_decrease_fragment_ttls: ;;; TODO: create fragmented packets align 4 -IPv4_create_Packet: +IPv4_create_packet: DEBUGF 1,"Create IPv4 Packet\n" @@ -515,11 +517,10 @@ IPv4_create_Packet: 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" @@ -528,9 +529,15 @@ IPv4_create_Packet: 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 @@ IPv4_create_Packet: 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,20 +580,18 @@ IPv4_create_Packet: 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 ret -uglobal - temp_dstmac dp ? ; TODO: place this in stack instead! -endg - ;--------------------------------------------------------------------------- ; diff --git a/kernel/branches/net/network/ethernet.inc b/kernel/branches/net/network/ethernet.inc index ed2e56f422..a222074b04 100644 --- a/kernel/branches/net/network/ethernet.inc +++ b/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 ;; @@ -45,6 +45,12 @@ struct ETH_DEVICE ends ; the rest of the device struct depends on the type of device +align 4 +iglobal + + ETH_BROADCAST dp 0xffffffffffff +endg + align 4 uglobal @@ -230,7 +236,7 @@ ETH_Receiver: ;------------------------------------------------------------- align 4 -ETH_Handler: +ETH_handler: get_from_queue ETH_IN_QUEUE, ETH_QUEUE_SIZE, .gohome @@ -243,10 +249,10 @@ ETH_Handler: 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,26 +383,22 @@ ETH_create_Packet: 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 pop ecx mov esi, ETH_Sender - xor edx, edx ;;;; TODO: Fixme + xor edx, edx ;;;; TODO: Fixme mov edx, [ETH_DRV_LIST + edx] DEBUGF 1,"done: %x size:%u device:%x\n", eax, ebx, edx diff --git a/kernel/branches/net/network/icmp.inc b/kernel/branches/net/network/icmp.inc index 2f1b8a7843..9cc0ec0a7f 100644 --- a/kernel/branches/net/network/icmp.inc +++ b/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 @@ ICMP_init: ;-------------------------------- 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 @@ ICMP_Handler: ;TODO: works only on pure ethernet right now ! ;-------------------------------- 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 @@ ICMP_Handler_fragments: ; works only on pure ethernet right now ! 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 @@ ICMP_Handler_fragments: ; works only on pure ethernet right now ! ;----------------------------------------------------------------- align 4 -ICMP_create_Packet: +ICMP_create_packet: DEBUGF 1,"Create ICMP Packet\n" @@ -382,7 +382,7 @@ ICMP_create_Packet: mov di , IP_PROTO_ICMP shr edx, 16 - call IPv4_create_Packet + call IPv4_create_packet cmp edi, -1 je .exit diff --git a/kernel/branches/net/network/queue.inc b/kernel/branches/net/network/queue.inc index 450de04e03..418ce3d8d2 100644 --- a/kernel/branches/net/network/queue.inc +++ b/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 ;; diff --git a/kernel/branches/net/network/socket.inc b/kernel/branches/net/network/socket.inc index 494cb41b20..f3cadb53d7 100644 --- a/kernel/branches/net/network/socket.inc +++ b/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 @@ struct SOCKET .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 @@ s_error: ; ; 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 @@ socket_open: 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_open: ; ; SOCKET_bind ; -; ; IN: socket number in ecx ; pointer to sockaddr struct in edx ; length of that struct in esi @@ -184,6 +185,7 @@ socket_bind: 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 @@ socket_connect: .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 @@ socket_send: 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 @@ socket_send: 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 diff --git a/kernel/branches/net/network/stack.inc b/kernel/branches/net/network/stack.inc index af213349cd..a6d200114c 100644 --- a/kernel/branches/net/network/stack.inc +++ b/kernel/branches/net/network/stack.inc @@ -110,7 +110,7 @@ stack_handler: 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 @@ endp 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 @@ sys_network: test bl, bl ; 0 = Get device type (ethernet/token ring/...) jnz @f - + ; todo xor eax, eax jmp .return diff --git a/kernel/branches/net/network/tcp.inc b/kernel/branches/net/network/tcp.inc index 57abab07c1..0d46595d29 100644 --- a/kernel/branches/net/network/tcp.inc +++ b/kernel/branches/net/network/tcp.inc @@ -1,20 +1,19 @@ -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; ;; -;; Copyright (C) KolibriOS team 2004-2008. All rights reserved. ;; -;; Distributed under terms of the GNU General Public License ;; -;; ;; -;; TCP.INC ;; -;; ;; -;; TCP Processes for Menuet OS TCP/IP stack ;; -;; ;; -;; Copyright 2002 Mike Hibbett, mikeh@oceanfree.net ;; -;; ;; -;; 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 ;; -;; ;; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; Copyright (C) KolibriOS team 2004-2009. All rights reserved. ;; +;; Distributed under terms of the GNU General Public License ;; +;; ;; +;; TCP.INC ;; +;; ;; +;; Part of the tcp/ip network stack for KolibriOS ;; +;; ;; +;; Written by hidnplayr@kolibrios.org ;; +;; ;; +;; GNU GENERAL PUBLIC LICENSE ;; +;; Version 2, June 1991 ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + $Revision: 1019 $ @@ -39,18 +38,20 @@ TH_PUSH equ 0x08 TH_ACK equ 0x10 TH_URG equ 0x20 -TWOMSL equ 10 ; # of secs to wait before closing socket +TWOMSL equ 10 ; # of secs to wait before closing socket -TCP_RETRIES equ 5 ; Number of times to resend a Packet -TCP_TIMEOUT equ 10 ; resend if not replied to in x hs +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 ? .SequenceNumber dd ? .AckNumber dd ? - .DataOffset db ? ; DataOffset[0-3 bits] and Reserved[4-7] - .Flags db ? ; Reserved[0-1 bits]|URG|ACK|PSH|RST|SYN|FIN + .DataOffset db ? ; DataOffset[0-3 bits] and Reserved[4-7] + .Flags db ? ; Reserved[0-1 bits]|URG|ACK|PSH|RST|SYN|FIN .Window dw ? .Checksum dw ? .UrgentPointer dw ? @@ -59,17 +60,59 @@ struct TCP_Packet .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 @@ tcp_tcb_handler: 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 @@ tcp_tcb_handler: ; ;*************************************************************************** -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 @@ proc tcp_tx_handler stdcall 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 @@ proc tcp_tx_handler stdcall @@: ; 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 @@ proc tcp_tx_handler stdcall .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 @@ proc tcp_tx_handler stdcall 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,35 +265,32 @@ proc tcp_tx_handler stdcall .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 @@ -265,19 +306,19 @@ proc tcp_rx stdcall uses ebx ; 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 @@ proc tcp_rx stdcall uses ebx ; 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 @@ proc tcp_rx stdcall uses ebx ; 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 @@ proc tcp_rx stdcall uses ebx ; 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 @@ proc tcp_rx stdcall uses ebx stdcall tcpStateMachine, ebx .exit: - pop eax - call freeBuff - ret -endp + + call kernel_free + add esp, 4 ; pop (balance stack) + +ret + +;----------------------------------------------------------------- +; +; 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,44 +450,45 @@ endp ; ;*************************************************************************** -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 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 @@ proc build_tcp_Packet stdcall, sockAddr:DWORD @@: ; 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, 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, [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 ; 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 @@ proc tcpStateMachine stdcall, sockAddr:DWORD 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 @@ proc tcpStateMachine stdcall, sockAddr:DWORD 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 @@ proc stateTCB_LISTEN stdcall, sockAddr:DWORD ; 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 @@ proc stateTCB_SYN_SENT stdcall, sockAddr:DWORD ; 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 @@ proc stateTCB_SYN_SENT stdcall, sockAddr:DWORD 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 @@ proc stateTCB_ESTABLISHED stdcall, sockAddr:DWORD 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 @@ proc stateTCB_ESTABLISHED stdcall, sockAddr:DWORD ; 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 @@ proc stateTCB_ESTABLISHED stdcall, sockAddr:DWORD .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 @@ proc stateTCB_ESTABLISHED stdcall, sockAddr:DWORD 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 @@ proc stateTCB_FIN_WAIT_1 stdcall, sockAddr:DWORD 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 @@ proc stateTCB_FIN_WAIT_1 stdcall, sockAddr:DWORD 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,29 +1107,29 @@ proc stateTCB_FIN_WAIT_2 stdcall, sockAddr:DWORD 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 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 @@ endp ; @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 @@ local sockAddr dd ? 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 @@ local sockAddr dd ? 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 @@ local sockAddr dd ? 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 @@ local sockAddr dd ? 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,28 +1278,28 @@ local sockAddr dd ? ; 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 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 @@ local sockAddr dd ? .error: or eax, -1 ret -endp +;endp @@ -1262,10 +1329,10 @@ endp 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 @@ cs1: loopw cs1 cs1_1: - and word [checkSize1], 0x01 +; and word [checkSize1], 0x01 jz cs_test2 mov bh, [eax] @@ -1288,11 +1355,11 @@ cs1_1: 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 @@ cs2: loopw cs2 cs2_1: - and word [checkSize2], 0x01 +; and word [checkSize2], 0x01 jz cs_exit mov bh, [eax] @@ -1326,21 +1393,7 @@ cs_exit: 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 - - - diff --git a/kernel/branches/net/network/udp.inc b/kernel/branches/net/network/udp.inc index c143d4ca4e..0a2c722a81 100644 --- a/kernel/branches/net/network/udp.inc +++ b/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_init: ; ;----------------------------------------------------------------- -UDP_Handler: +UDP_handler: DEBUGF 1,"UDP_Handler\n" ; TODO: First validate the header & checksum. Discard buffer if error @@ -110,7 +110,6 @@ UDP_Handler: @@: 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 @@ UDP_Handler: ; 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 @@ UDP_create_Packet: ; 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 @@ UDP_create_Packet: 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