diff --git a/src/app/app.dhclient.pas b/src/app/app.dhclient.pas index e7d59bc9..03972429 100644 --- a/src/app/app.dhclient.pas +++ b/src/app/app.dhclient.pas @@ -22,7 +22,7 @@ unit app.dhclient; interface uses - io.stdio, core.util, arch.x86.util, core.strings, debug.tracer, driver.net.proto.dhcp; + io.stdio, core.util, arch.platform.cpu, core.strings, debug.tracer, driver.net.proto.dhcp; procedure init(); diff --git a/src/app/app.ping.pas b/src/app/app.ping.pas index 76d72624..ae841cd4 100644 --- a/src/app/app.ping.pas +++ b/src/app/app.ping.pas @@ -20,8 +20,8 @@ procedure init(); implementation uses - arch.x86.bda, driver.net.types, driver.net.proto.icmp, driver.net.util, core.strings, - proc.mgr, core.util, arch.x86.util, memory.heap; + proc.types, driver.net.types, driver.net.proto.icmp, driver.net.util, core.strings, + proc.mgr, core.util, arch.platform.cpu, memory.heap; const PING_TIMEOUT_MS = 5000; { 5-second timeout per app.ping } @@ -31,22 +31,34 @@ type PPingState = ^TPingState; TPingState = record Result : TPingResult; - ReplyTimeMS : uint64; + ReplyTimeMS : uint32; ErrorReason : TARPErrorCode; - SendTime : uint64; + SendTime : uint32; + Address : puint8; end; +procedure cleanup(handle: void); +var + st: PPingState; +begin + st := PPingState(handle); + if st = nil then exit; + driver.net.proto.icmp.cancelRequests(handle); + kfree(void(st^.Address)); + kfree(handle); +end; + { ---- ICMP callbacks (called from network recv context) ---- } procedure on_reply(hdr : PICMPHeader; userData : void); var st : PPingState; - t2 : uint64; + t2 : uint32; begin st := PPingState(userData); if st = nil then exit; - t2 := Counters.c64; - st^.ReplyTimeMS := t2 - st^.SendTime; + t2 := networkTicks; + st^.ReplyTimeMS := (uint64(uint32(t2 - st^.SendTime)) * 1000) div 1024; st^.Result := prGotReply; end; @@ -87,24 +99,31 @@ begin { Allocate per-invocation state so concurrent pings are safe } st := PPingState(kalloc(sizeof(TPingState))); + if st = nil then begin + kfree(void(ip)); + exit; + end; + st^.Address := ip; + proc.mgr.bindResource(proc.mgr.CurrentProcess, rkCustom, void(st), @cleanup); timeoutTicks := (PING_TIMEOUT_MS * 1024) div 1000; for i := 0 to 9 do begin { Send ICMP echo request } st^.Result := prWaiting; - st^.SendTime := Counters.c64; + st^.SendTime := networkTicks; driver.net.proto.icmp.sendICMPRequest(ip, i, 128, @on_reply, @on_error, void(st)); { Spin-yield until callback fires or timeout } - tStart := Counters.c32; + tStart := networkTicks; while st^.Result = prWaiting do begin proc.mgr.proc_yield; - tNow := Counters.c32; + tNow := networkTicks; if tNow >= tStart then elapsed := tNow - tStart else elapsed := ($FFFFFFFF - tStart) + tNow + 1; if elapsed >= timeoutTicks then begin + driver.net.proto.icmp.cancelRequests(void(st)); st^.Result := prGotError; st^.ErrorReason := aecTimeout; break; @@ -132,8 +151,7 @@ begin end; { Clean up } - kfree(void(st)); - kfree(void(ip)); + proc.mgr.unbindResource(proc.mgr.CurrentProcess, void(st)); end; procedure init(); @@ -142,4 +160,4 @@ begin io.stdio.registerCommand('PING', @run, 'Ping a host.'); end; -end. \ No newline at end of file +end. diff --git a/src/driver/net/dev/driver.net.dev.e1000.pas b/src/driver/net/dev/driver.net.dev.e1000.pas index dfd47739..5e92c389 100644 --- a/src/driver/net/dev/driver.net.dev.e1000.pas +++ b/src/driver/net/dev/driver.net.dev.e1000.pas @@ -22,22 +22,20 @@ unit driver.net.dev.e1000; interface uses - boot.mgr, debug.tracer, io.syslog, io.stdio, core.strings, - arch.x86.memory.virtual, + arch.platform.memory, memory.heap, driver.mgr, driver.types, - core.util, arch.x86.util, - arch.x86.idt, + core.util, arch.platform.cpu, driver.bus.pci, driver.net, driver.net.types, driver.net.util, - arch.x86.isr.mgr; + arch.platform.interrupts; const INTEL_VEND = $8086; @@ -165,7 +163,7 @@ var card_type : TCardType; bar_type : uint8; io_base : uint16; - mem_base : uint64; + mem_base : PtrUInt; eeprom_exists : boolean; mac : array[0..5] of uint8; rx_descs : array[0..E1000_NUM_RX_DESC-1] of PE1000_rx_desc; @@ -173,7 +171,8 @@ var rx_buffs : array[0..E1000_NUM_RX_DESC-1] of puint8; rx_curr : uint16; tx_curr : uint16; - mem_aloc : boolean = false; + dmaAllocation: void; + dmaBase: PtrUInt; procedure writeCommand(p_address : uint16; p_value : uint32); var @@ -225,24 +224,24 @@ end; function EEPROMRead( address : uint8 ) : uint32; var - data : uint16; - tmp : uint32; + tmp, mask, attempt: uint32; begin - tmp:= 0; + EEPROMRead := $FFFFFFFF; if (eeprom_exists) then begin writeCommand( REG_EEPROM, 1 OR (uint32(address) SHL 8) ); - while (tmp AND (1 SHL 4)) = 0 do begin - tmp:= readCommand(REG_EEPROM); //Might be wrong? - end; + mask := 1 shl 4; end else begin writeCommand( REG_EEPROM, 1 OR (uint32(address) SHL 2) ); - while (tmp AND (1 SHL 1)) = 0 do begin - tmp:= readCommand(REG_EEPROM); //Might be wrong? + mask := 1 shl 1; + end; + for attempt := 0 to 9999 do begin + tmp := readCommand(REG_EEPROM); + if tmp and mask <> 0 then begin + EEPROMRead := tmp shr 16; + exit; end; end; - data:= uint16( (tmp SHR 16) AND ($FFFF) ); - EEPROMRead:= data; end; function readMACAddress() : boolean; @@ -258,19 +257,31 @@ begin res:= true; if (eeprom_exists) then begin temp:= EEPROMRead(0); + if temp = $FFFFFFFF then begin + readMACAddress := false; + exit; + end; mac[0]:= temp AND $FF; mac[1]:= temp SHR 8; temp:= EEPROMRead(1); + if temp = $FFFFFFFF then begin + readMACAddress := false; + exit; + end; mac[2]:= temp AND $FF; mac[3]:= temp SHR 8; temp:= EEPROMRead(2); + if temp = $FFFFFFFF then begin + readMACAddress := false; + exit; + end; mac[4]:= temp AND $FF; mac[5]:= temp SHR 8; end else begin mem_base_mac_8:= puint8(mem_base + $5400); mem_base_mac_32:= puint32(mem_base + $5400); if (mem_base_mac_32[0] <> 0) then begin - for i:=0 to 6 do begin + for i:=0 to 5 do begin mac[i]:= mem_base_mac_8[i]; end; end else begin @@ -289,89 +300,59 @@ begin writeCommand(REG_CTRL, val OR ECTRL_SLU); end; -procedure rxinit(); +{ Each DMA object fits within one aligned 4 KiB page. The heap allocation + remains owned by the loaded driver; physical pages need not be adjacent. } +procedure rxinit; var - ptr : puint8; - outptr : puint8; - descs : PE1000_rx_desc; - i : uint32; - + physical: uint64; + descs: PE1000_rx_desc; + i: uint32; begin - ptr:= puint8(kalloc(sizeof(TE1000_rx_desc) * E1000_NUM_RX_DESC + 16)); - descs:= PE1000_rx_desc(ptr); - for i:=0 to E1000_NUM_RX_DESC do begin - rx_descs[i]:= @descs[i];//PE1000_rx_desc(uint32(descs) + i*16); - rx_buffs[i]:= puint8(kalloc(8192 + 16)); - rx_descs[i]^.address:= uint64(vtop(uint32(rx_buffs[i]))); - rx_descs[i]^.status:= 0; + descs := PE1000_rx_desc(dmaBase); + for i := 0 to E1000_NUM_RX_DESC - 1 do begin + rx_descs[i] := @descs[i]; + rx_buffs[i] := puint8(dmaBase + (2 + i) * 4096); + rx_descs[i]^.address := physicalAddress(PtrUInt(rx_buffs[i])); + rx_descs[i]^.status := 0; end; - - outptr:= puint8(vtop(uint32(ptr)));//puint8(uint32(ptr) - KERNEL_VIRTUAL_BASE); - - io.syslog.log('driver.net.dev.e1000 Driver', 'RX VMem: '); - io.syslog.writehexln(uint32(ptr)); - io.syslog.log('driver.net.dev.e1000 Driver', 'RX Mem: '); - io.syslog.writehexln(uint32(outptr)); - - writeCommand(REG_TXDESCLO, uint32(uint64(outptr) SHR 32)); - writeCommand(REG_TXDESCHI, uint32(uint64(outptr) AND $FFFFFFFF)); - - writeCommand(REG_RXDESCLO, uint32(outptr)); - writeCommand(REG_RXDESCHI, 0); - + physical := physicalAddress(dmaBase); + writeCommand(REG_RXDESCLO, uint32(physical)); + writeCommand(REG_RXDESCHI, uint32(physical shr 32)); writeCommand(REG_RXDESCLEN, E1000_NUM_RX_DESC * sizeof(TE1000_rx_desc)); - writeCommand(REG_RXDESCHEAD, 0); - writeCommand(REG_RXDESCTAIL, E1000_NUM_RX_DESC-1); - rx_curr:= 0; - - writeCommand(REG_RCTRL, RCTL_EN OR RCTL_SBP OR RCTL_UPE OR RCTL_MPE OR RCTL_LBM_NONE OR RTCL_RDMTS_HALF OR RCTL_BAM OR RCTL_SECRC OR RCTL_BSIZE_2048); + writeCommand(REG_RXDESCTAIL, E1000_NUM_RX_DESC - 1); + rx_curr := 0; + writeCommand(REG_RCTRL, RCTL_EN or RCTL_BAM or RCTL_SECRC or RCTL_BSIZE_2048); end; -procedure txinit(); +procedure txinit; var - ptr : puint8; - outptr : puint8; - descs : PE1000_tx_desc; - i : uint32; - + physical: uint64; + descs: PE1000_tx_desc; + i: uint32; begin - ptr:= puint8(kalloc(sizeof(TE1000_tx_desc) * (E1000_NUM_TX_DESC + 16))); - descs:= PE1000_tx_desc(ptr); - for i:=0 to E1000_NUM_TX_DESC do begin - tx_descs[i]:= @descs[i];//PE1000_tx_desc(uint32(descs + i*16)); - tx_descs[i]^.address:= 0; - tx_descs[i]^.cmd:= 0; - tx_descs[i]^.status:= TSTA_DD; + descs := PE1000_tx_desc(dmaBase + 4096); + for i := 0 to E1000_NUM_TX_DESC - 1 do begin + tx_descs[i] := @descs[i]; + tx_descs[i]^.address := physicalAddress(dmaBase + + (2 + E1000_NUM_RX_DESC + i) * 4096); + tx_descs[i]^.status := TSTA_DD; end; - - outptr:= puint8(vtop(uint32(ptr))); //puint8(uint32(ptr) - KERNEL_VIRTUAL_BASE); - - io.syslog.writehexln(uint32(ptr)); - io.syslog.writehexln(uint32(outptr)); - - writeCommand(REG_TXDESCHI, 0); - writeCommand(REG_TXDESCLO, uint32(outptr)); - + physical := physicalAddress(PtrUInt(descs)); + writeCommand(REG_TXDESCLO, uint32(physical)); + writeCommand(REG_TXDESCHI, uint32(physical shr 32)); writeCommand(REG_TXDESCLEN, E1000_NUM_TX_DESC * sizeof(TE1000_tx_desc)); - - writeCommand( REG_TXDESCHEAD, 0 ); - writeCommand( REG_TXDESCTAIL, 0 ); - tx_curr:= 0; - writeCommand(REG_TCTRL, TCTL_EN OR TCTL_PSP OR (15 SHL TCTL_CT_SHIFT) OR (64 SHL TCTL_COLD_SHIFT) OR TCTL_RTLC); - - //The following is needed for I217 & 82577LM - if (card_type = ct82577LM) OR (card_type = ctI217) then begin - writeCommand(REG_TCTRL, $3003F0FA); - writeCommand(REG_TIPG, $0060200A); - end; + writeCommand(REG_TXDESCHEAD, 0); + writeCommand(REG_TXDESCTAIL, 0); + tx_curr := 0; + writeCommand(REG_TCTRL, TCTL_EN or TCTL_PSP or + (15 shl TCTL_CT_SHIFT) or (64 shl TCTL_COLD_SHIFT) or TCTL_RTLC); + writeCommand(REG_TIPG, $0060200A); end; - procedure enableInturrupt(); begin - writeCommand(REG_IMASK, $1F6DC); - writeCommand(REG_IMASK, $FF AND NOT(4)); readCommand($C0); + writeCommand(REG_IMASK, $84); end; procedure handleReceive(); @@ -383,13 +364,18 @@ var i : uint16; begin - while (rx_descs[rx_curr]^.status AND $1) > 0 do begin + i := 0; + while ((rx_descs[rx_curr]^.status and $1) <> 0) and + (i < E1000_NUM_RX_DESC) do begin + inc(i); got_packet:= true; buf:= rx_buffs[rx_curr]; len:= rx_descs[rx_curr]^.length; //Inject Packet into Network Stack - driver.net.recv(void(buf), len); + if ((rx_descs[rx_curr]^.status and $2) <> 0) and + (rx_descs[rx_curr]^.errors = 0) and (len >= 14) and (len <= 2048) then + driver.net.recv(void(buf), len); rx_descs[rx_curr]^.status:= 0; old_cur:= rx_curr; @@ -425,8 +411,7 @@ begin if (Status AND $80) > 0 then begin handleReceive(); end; - //Clear the INT on the Device First by using write-1 - writeCommand(REG_IMASK, 1); + { Reading ICR above acknowledges the device interrupt. } end; procedure console_command_mac(params : PParamList; stdin_buf, stdout_buf, stderr_buf : POutBuf); @@ -512,6 +497,7 @@ var begin push_trace('driver.net.dev.e1000.load'); + load := false; io.syslog.logln('driver.net.dev.e1000 Driver', 'Load Start.'); @@ -519,12 +505,13 @@ begin PCI_Info:= PPCI_Device(ptr); bar_type:= PCI_Info^.address0 AND $00000001; - io_base:= PCI_Info^.address0 AND $FFFFFFF0; - mem_base:= PCI_INFO^.address0 AND $FFFFFFFC; - - { !!!!! Dirty way to alloc the pages, needs fixing !!!!! } - kpalloc(io_base); - kpalloc(mem_base); + io_base := PCI_Info^.address0 and $FFFFFFFC; + if bar_type = 0 then begin + mem_base := PtrUInt(mapDevice(PCI_Info^.address0 and $FFFFFFF0, $20000)); + if mem_base = 0 then exit; + end; + if PCI_Info^.interrupt_line >= 16 then exit; + writeCommand($D8, $FFFFFFFF); bus:= PCI_Info^.bus; slot:= PCI_Info^.slot; @@ -548,18 +535,20 @@ begin startLink(); - for i:=0 to $80 do begin + for i:=0 to $7F do begin writeCommand($5200 + i*4, 0); end; - driver.net.registerNetworkCard(@sendPacket, getMACAddress()); - - arch.x86.isr.mgr.registerISR(32 + PCI_Info^.interrupt_line, @fire); - enableInturrupt(); - + dmaAllocation := kalloc((2 + E1000_NUM_RX_DESC + E1000_NUM_TX_DESC) * 4096 + 4095); + if dmaAllocation = nil then exit; + dmaBase := (PtrUInt(dmaAllocation) + 4095) and not PtrUInt(4095); rxinit(); txinit(); - + loaded := true; + driver.net.registerNetworkCard(@sendPacket, getMACAddress()); + arch.platform.interrupts.registerIRQ(32 + PCI_Info^.interrupt_line, @fire); + arch.platform.interrupts.routePCI(PCI_Info^.interrupt_line, 32 + PCI_Info^.interrupt_line); + enableInturrupt(); load:= true; if load then registercommand('E1000', @terminal_command_e1000status, 'driver.net.dev.e1000 Information.'); @@ -627,26 +616,22 @@ end; function sendPacket(p_data : void; p_len : uint16) : sint32; var - old_cur : uint8; - timeout : uint32; - + flags, buffer: PtrUInt; begin - tx_descs[tx_curr]^.address:= uint32(vtop(uint32(p_data))); - tx_descs[tx_curr]^.length:= p_len; - tx_descs[tx_curr]^.cmd:= CMD_EOP OR CMD_IFCS OR CMD_RS OR CMD_RPS; - tx_descs[tx_curr]^.status:= 0; - old_cur:= tx_curr; - tx_curr:= (tx_curr + 1) MOD E1000_NUM_TX_DESC; - writeCommand(REG_TXDESCTAIL, tx_curr); - timeout:= 1000000; - while ((tx_descs[old_cur]^.status AND $FF) = 0) and (timeout > 0) do begin - dec(timeout); + sendPacket := 1; + if (not loaded) or (p_data = nil) or (p_len = 0) or (p_len > 2048) then exit; + flags := arch.platform.cpu.lock; + if (tx_descs[tx_curr]^.status and TSTA_DD) <> 0 then begin + buffer := dmaBase + (2 + E1000_NUM_RX_DESC + tx_curr) * 4096; + memcpy(PtrUInt(p_data), buffer, p_len); + tx_descs[tx_curr]^.length := p_len; + tx_descs[tx_curr]^.cmd := CMD_EOP or CMD_IFCS or CMD_RS; + tx_descs[tx_curr]^.status := 0; + tx_curr := (tx_curr + 1) mod E1000_NUM_TX_DESC; + writeCommand(REG_TXDESCTAIL, tx_curr); + sendPacket := 0; end; - sendPacket:= 1; - if timeout > 0 then sendPacket:= 0; + arch.platform.cpu.unlock(flags); end; -Initialization - //boot.mgr.registerBoot('driver.net.dev.e1000', @Init, 'E1000 Network Card Driver', BOOT_MGR_BARRIER_DEVICE) - end. diff --git a/src/driver/net/driver.net.pas b/src/driver/net/driver.net.pas index 426856fb..bb65f6c6 100644 --- a/src/driver/net/driver.net.pas +++ b/src/driver/net/driver.net.pas @@ -22,7 +22,6 @@ unit driver.net; interface uses - boot.mgr, debug.tracer, driver.net.types, driver.net.util, io.syslog, @@ -40,7 +39,7 @@ procedure writeToLogLn(str : pchar); implementation uses - driver.net.dev.e1000, //dev + io.stdio, driver.net.dev.e1000, //dev driver.net.proto.eth2, //L2 driver.net.proto.arp, driver.net.proto.ipv4, //L3 driver.net.proto.icmp, driver.net.proto.tcp, driver.net.proto.udp, //L4 @@ -141,10 +140,14 @@ begin driver.net.proto.udp.register; //l5 driver.net.proto.dhcp.register; + driver.net.dev.e1000.init; + io.stdio.registerCommand('ARP', @driver.net.proto.arp.terminal_command_arp, 'Get ARP Table.'); + io.stdio.registerCommand('IFCONFIG', @driver.net.proto.ipv4.terminal_command_ifconfig, 'Configure Network Settings.'); + io.stdio.registerCommand('TCPCONNECT', @driver.net.proto.tcp.terminal_command_tcpconnect, 'Connect to a TCP host and send Hello World.'); + io.stdio.registerCommand('TCPLISTEN', @driver.net.proto.tcp.terminal_command_tcplisten, 'Listen on a TCP port and log received data.'); + io.stdio.registerCommand('TCPHTTP', @driver.net.proto.tcp.terminal_command_tcphttp, 'Send HTTP GET to a host IP (port 80 default).'); pop_trace; end; -initialization - boot.mgr.registerBoot('driver.net', @Init, 'Net Driver', BOOT_MGR_BARRIER_LATE) -end. \ No newline at end of file +end. diff --git a/src/driver/net/driver.net.util.pas b/src/driver/net/driver.net.util.pas index e391e51f..1bd54656 100644 --- a/src/driver/net/driver.net.util.pas +++ b/src/driver/net/driver.net.util.pas @@ -22,7 +22,7 @@ unit driver.net.util; interface uses - debug.tracer, core.util, arch.x86.util, driver.net.types, io.stdio, memory.heap, core.ds.lists, core.strings; + debug.tracer, core.util, arch.platform.cpu, driver.net.types, io.stdio, memory.heap, core.ds.lists, core.strings; procedure copyMAC(src : puint8; dst : puint8); procedure copyIPv4(src : puint8; dst : puint8); @@ -41,9 +41,21 @@ function verifyChecksum(p_data : puint16; p_len : uint16) : boolean; function sameSubnetIPv4(ip1, ip2, netmask : puint8) : boolean; procedure contextMACSwitch(p_context : PPacketContext); procedure contextIPv4Switch(p_context : PPacketContext); +function networkTicks: uint32; implementation +uses arch.platform.interrupts, arch.common.legacyirq; + +function networkTicks: uint32; +var + ticks: uint64; +begin + ticks := arch.platform.interrupts.timerTicks; + networkTicks := uint32((ticks div PIT_INPUT_HZ) * PIT_DIVISOR * 1024 + + ((ticks mod PIT_INPUT_HZ) * PIT_DIVISOR * 1024) div PIT_INPUT_HZ); +end; + function sameSubnetIPv4(ip1, ip2, netmask : puint8) : boolean; var _ip1, _ip2, _netmask : puint32; @@ -232,7 +244,7 @@ function newPacketContext : PPacketContext; begin push_trace('driver.net.util.newPacketContext'); newPacketContext:= PPacketContext(kalloc(sizeof(TPacketContext))); - memset(uint32(newPacketContext), 0, sizeof(TPacketContext)); + memset(PtrUInt(newPacketContext), 0, sizeof(TPacketContext)); pop_trace; end; @@ -267,4 +279,4 @@ begin pop_trace; end; -end. \ No newline at end of file +end. diff --git a/src/driver/net/proto/driver.net.proto.arp.pas b/src/driver/net/proto/driver.net.proto.arp.pas index 50baaf36..558962ea 100644 --- a/src/driver/net/proto/driver.net.proto.arp.pas +++ b/src/driver/net/proto/driver.net.proto.arp.pas @@ -23,7 +23,7 @@ interface uses debug.tracer, memory.heap, - core.util, arch.x86.util, core.ds.lists, + core.util, arch.platform.cpu, core.ds.lists, driver.net, driver.net.types, driver.net.util, driver.net.proto.eth2, driver.net.proto.ipv4, io.stdio; @@ -212,6 +212,7 @@ var begin push_trace('driver.net.proto.arp.recv'); + if (p_data = nil) or (p_len < sizeof(TARPHeader)) then exit; { Get our converted Header } Header:= PARPHeader(p_data); AHeader.Hardware_Type:= (Header^.Hardware_Type_Hi SHL 8) + Header^.Hardware_Type_Lo; @@ -345,4 +346,4 @@ begin pop_trace; end; -end. \ No newline at end of file +end. diff --git a/src/driver/net/proto/driver.net.proto.dhcp.pas b/src/driver/net/proto/driver.net.proto.dhcp.pas index 4e55f466..45f1c624 100644 --- a/src/driver/net/proto/driver.net.proto.dhcp.pas +++ b/src/driver/net/proto/driver.net.proto.dhcp.pas @@ -24,7 +24,7 @@ interface uses memory.heap, io.syslog, driver.net.types, driver.net.util, driver.net.proto.udp, driver.net, - core.util, arch.x86.util, core.rand, core.ds.lists, debug.tracer, driver.net.proto.ipv4, driver.net.proto.arp; + core.util, arch.platform.cpu, core.rand, core.ds.lists, debug.tracer, driver.net.proto.ipv4, driver.net.proto.arp; type TDHCPOptions = PLinkedListBase; @@ -95,10 +95,10 @@ begin CopyIPv4(@NULL_IP[0], @result^.Relay_Agent_IP[0]); MAC:= getMAC; CopyMAC(MAC, @result^.Client_MAC[0]); - memset(uint32(@result^.Padding[0]), 0, 10); - memset(uint32(@result^.Server_Hostname[0]), 0, 64); - memset(uint32(@result^.Boot_File[0]), 0, 128); - memcpy(uint32(@DHCP_MAGIC[0]), uint32(@result^.Magic_Cookie[0]), 4); + memset(PtrUInt(@result^.Padding[0]), 0, 10); + memset(PtrUInt(@result^.Server_Hostname[0]), 0, 64); + memset(PtrUInt(@result^.Boot_File[0]), 0, 128); + memcpy(PtrUInt(@DHCP_MAGIC[0]), PtrUInt(@result^.Magic_Cookie[0]), 4); createHeader:= result; end; @@ -115,7 +115,7 @@ begin Option^.Reverse_Endian:= SwapEndian; if Length > 0 then begin Option^.Value:= kalloc(Length); - memcpy(uint32(Data), uint32(Option^.Value), Length); + memcpy(PtrUInt(Data), PtrUInt(Option^.Value), Length); end else begin Option^.Value:= nil; end; @@ -292,7 +292,7 @@ begin { Copy the header } NewHeader:= PDHCPHeader(NewBuffer); - memcpy(uint32(Header), uint32(NewHeader), sizeof(TDHCPHeader)); + memcpy(PtrUInt(Header), PtrUInt(NewHeader), sizeof(TDHCPHeader)); { Write Options } buffer:= puint8(NewBuffer); @@ -322,7 +322,7 @@ begin read32^:= getEndianCorrectValue32(Option); end; else begin - memcpy(uint32(Option^.Value), uint32(buffer), Option^.Size); + memcpy(PtrUInt(Option^.Value), PtrUInt(buffer), Option^.Size); end; end; inc(buffer, Option^.Size); @@ -354,8 +354,8 @@ begin { Get the beginning & end of the Options buffer } HeaderSize:= sizeOf(TDHCPHeader); - bufferEnd:= puint8(uint32(p_data) + p_len); - bufferStart:= puint8(uint32(p_data) + headerSize); + bufferEnd:= puint8(PtrUInt(p_data) + p_len); + bufferStart:= puint8(PtrUInt(p_data) + headerSize); { Buffer is our iterator } buffer:= bufferStart; @@ -363,13 +363,14 @@ begin HaveOp:= false; HaveLen:= false; - while (uint32(buffer) < uint32(bufferEnd)) do begin + while (PtrUInt(buffer) < PtrUInt(bufferEnd)) do begin { If we have a length, read the value (bytes[length]) If we have an Opcode read the length (bytes[1]) If we have neither, read the opcode (bytes[1]) } if HaveLen then begin + if Length > PtrUInt(bufferEnd) - PtrUInt(buffer) then exit; { Get a new option LinkedList 'object' and store everything inside } Option:= newOption(DHCPOptions, Opcode, void(buffer), Length, not FlipExclude^[ord(Opcode)]); if Length = 2 then begin @@ -445,7 +446,7 @@ begin else begin cfgopt:= kalloc(Option^.Size); Configuration^.Options[ord(Option^.Opcode)]:= cfgopt; - memcpy(uint32(Option^.Value), uint32(cfgopt), Option^.Size); + memcpy(PtrUInt(Option^.Value), PtrUInt(cfgopt), Option^.Size); end; end; end; @@ -566,6 +567,7 @@ var begin debug.tracer.push_trace('driver.net.proto.dhcp.processPacket.enter'); + if (p_data = nil) or (p_len < sizeof(TDHCPHeader)) then exit; writeToLogLn(' L5/DHCP: processPacket'); io.syslog.logln('DHCP','processPacket'); @@ -795,4 +797,4 @@ begin io.syslog.logln('DHCP', 'Register end.'); end; -end. \ No newline at end of file +end. diff --git a/src/driver/net/proto/driver.net.proto.eth2.pas b/src/driver/net/proto/driver.net.proto.eth2.pas index ef779f22..0009207a 100644 --- a/src/driver/net/proto/driver.net.proto.eth2.pas +++ b/src/driver/net/proto/driver.net.proto.eth2.pas @@ -22,7 +22,7 @@ unit driver.net.proto.eth2; interface uses - memory.heap, core.util, arch.x86.util, + memory.heap, core.util, arch.platform.cpu, debug.tracer, driver.net.types, driver.net.util, driver.net, @@ -79,9 +79,9 @@ begin copyMAC(@p_context^.MAC.Destination[0], @hdr.dst[0]); hdr.EthTypeHi:= eth_type SHR 8; hdr.EthTypeLo:= eth_type AND $FF; - memcpy(uint32(@hdr), uint32(buffer), sizeof(TEthernetHeader)); - memcpy(uint32(p_data), uint32(buffer)+sizeof(TEthernetHeader), p_len); - //FCS:= puint32((uint32(buffer) + size) - 4); + memcpy(PtrUInt(@hdr), PtrUInt(buffer), sizeof(TEthernetHeader)); + memcpy(PtrUInt(p_data), PtrUInt(buffer)+sizeof(TEthernetHeader), p_len); + //FCS:= puint32((PtrUInt(buffer) + size) - 4); //FCS^:= crc32(puint8(buffer), size - 4); driver.net.send(buffer, size); kfree(buffer); @@ -96,6 +96,7 @@ var begin push_trace('driver.net.proto.eth2.recv'); + if (p_data = nil) or (p_len < sizeof(TEthernetHeader)) then exit; buf:= puint8(p_data); Header:= PEthernetHeader(buf); @@ -134,4 +135,4 @@ begin pop_trace; end; -end. \ No newline at end of file +end. diff --git a/src/driver/net/proto/driver.net.proto.icmp.pas b/src/driver/net/proto/driver.net.proto.icmp.pas index 76929881..91f3898c 100644 --- a/src/driver/net/proto/driver.net.proto.icmp.pas +++ b/src/driver/net/proto/driver.net.proto.icmp.pas @@ -22,9 +22,8 @@ unit driver.net.proto.icmp; interface uses - arch.x86.bda, memory.heap, debug.tracer, - driver.net, driver.net.types, driver.net.util, driver.net.proto.ipv4, driver.net.proto.arp, core.util, arch.x86.util; + driver.net, driver.net.types, driver.net.util, driver.net.proto.ipv4, driver.net.proto.arp, core.util, arch.platform.cpu; type TARPErrorCode = (aecFailedToResolveHost, aecNoRouteToHost, aecTimeout, aecTTLExpired); @@ -38,6 +37,7 @@ type end; procedure register; +procedure cancelRequests(userData: void); procedure sendICMPRequest(ip : puint8; Sequence : uint16; TTL : uint8; OnRep : TARPReplyCallback; OnErr : TARPErrorCallback; userData : void); implementation @@ -45,6 +45,23 @@ implementation var Handlers : Array[0..255] of TARPHandler; +procedure cancelRequests(userData: void); +var + i: uint32; + flags: PtrUInt; +begin + flags := arch.platform.cpu.lock; + for i := 1 to 255 do begin + if Handlers[i].UserData = userData then begin + Handlers[i].Active := false; + Handlers[i].UserData := nil; + Handlers[i].OnReply := nil; + Handlers[i].OnError := nil; + end; + end; + arch.platform.cpu.unlock(flags); +end; + function nextInactiveHandler : uint8; var i : uint8; @@ -74,15 +91,23 @@ var Buffer : void; CHK : uint16; Size : uint32; + flags : PtrUInt; begin push_trace('driver.net.proto.icmp.sendICMPRequest'); writeToLogLn(' L4/ICMP: sendICMPRequest'); + flags := arch.platform.cpu.lock; handle:= nextInactiveHandler; + if handle = 0 then begin + arch.platform.cpu.unlock(flags); + if OnErr <> nil then OnErr(nil, aecTimeout, userData); + exit; + end; Handlers[handle].Active:= true; Handlers[handle].OnReply:= OnRep; Handlers[handle].OnError:= OnErr; Handlers[handle].UserData:= userData; + arch.platform.cpu.unlock(flags); if SameSubnetIPv4(ip, @getIPv4Config^.Address[0], @getIPv4Config^.Netmask[0]) then begin dest_mac:= driver.net.proto.arp.resolveIP(ip); end else begin @@ -109,7 +134,7 @@ begin Header^.Identifier:= handle; Header^.Sequence:= Sequence; - memcpy(uint32(@ICMP_DATA_GENERIC[0]), uint32(Buffer) + sizeof(TICMPHeader), sizeof(ICMP_DATA_GENERIC)); + memcpy(PtrUInt(@ICMP_DATA_GENERIC[0]), PtrUInt(Buffer) + sizeof(TICMPHeader), sizeof(ICMP_DATA_GENERIC)); CHK:= calculateChecksum(puint16(Buffer), Size); @@ -117,6 +142,7 @@ begin Header^.ICMP_CHK_Lo:= CHK SHR 8; driver.net.proto.ipv4.send(Buffer, size, context); + kfree(Buffer); freePacketContext(context); end; @@ -135,6 +161,7 @@ var begin push_trace('driver.net.proto.icmp.recv'); + if (p_data = nil) or (p_len < sizeof(TICMPHeader)) then exit; writeToLogLn(' L4/ICMP: recv'); Header:= PICMPHeader(p_data); //writehexlnWND(Header^.ICMP_Type, getTerminalHWND); @@ -153,6 +180,7 @@ begin driver.net.proto.ipv4.send(p_data, p_len, p_context); end; $00:begin //Reply + if Header^.Identifier > 255 then exit; Handle:= Header^.Identifier; if (Handle > 0) and (Handle < 256) then begin If Handlers[Handle].Active then begin @@ -183,4 +211,4 @@ begin driver.net.proto.ipv4.registerProtocol($01, @recv); end; -end. \ No newline at end of file +end. diff --git a/src/driver/net/proto/driver.net.proto.ipv4.pas b/src/driver/net/proto/driver.net.proto.ipv4.pas index cf4dfff9..ec2c8a95 100644 --- a/src/driver/net/proto/driver.net.proto.ipv4.pas +++ b/src/driver/net/proto/driver.net.proto.ipv4.pas @@ -23,7 +23,7 @@ interface uses debug.tracer, memory.heap, - core.util, arch.x86.util, core.strings, + core.util, arch.platform.cpu, core.strings, driver.net, driver.net.types, driver.net.util, core.ds.lists, driver.net.proto.eth2, io.stdio; @@ -84,8 +84,8 @@ begin Header.HDR_CHK_Hi:= CHK AND $FF;//CHK SHR 8; Header.HDR_CHK_Lo:= CHK SHR 8;//CHK AND $FF; Buffer:= kalloc(Len); - memcpy(uint32(@Header), uint32(Buffer), Header.header_len * 4); - memcpy(uint32(p_data), uint32(Buffer) + (Header.header_len * 4), p_len); + memcpy(PtrUInt(@Header), PtrUInt(Buffer), Header.header_len * 4); + memcpy(PtrUInt(p_data), PtrUInt(Buffer) + (Header.header_len * 4), p_len); driver.net.proto.eth2.send(Buffer, (Header.header_len * 4) + p_len, $0800, p_context); kfree(Buffer); pop_trace; @@ -101,11 +101,15 @@ var begin push_trace('driver.net.proto.ipv4.recv'); + if (p_data = nil) or (p_len < 20) then exit; Header:= PIPV4Header(p_data); AHeader.version:= Header^.version; AHeader.header_len:= Header^.header_len; AHeader.ToS:= Header^.ToS; AHeader.total_len:= (Header^.total_len_Hi SHL 8) + Header^.total_len_Lo; + if (AHeader.version <> 4) or (AHeader.header_len < 5) or + (AHeader.total_len < AHeader.header_len * 4) or + (AHeader.total_len > p_len) then exit; AHeader.identifier:= (Header^.identifier_Hi SHL 8) + Header^.identifier_Lo; AHeader.Flags.RS:= false; AHeader.Flags.DF:= (Header^.Flags AND $2) > 0; @@ -122,7 +126,7 @@ begin buf:= puint8(p_data); buf:= buf + (AHeader.header_len * 4); - len:= p_len - (AHeader.header_len * 4); + len:= AHeader.total_len - (AHeader.header_len * 4); copyIPv4(@AHeader.Src[0], @p_context^.IP.Source[0]); copyIPv4(@AHeader.Dst[0], @p_context^.IP.Destination[0]); @@ -225,4 +229,4 @@ begin pop_trace; end; -end. \ No newline at end of file +end. diff --git a/src/driver/net/proto/driver.net.proto.tcp.pas b/src/driver/net/proto/driver.net.proto.tcp.pas index d64e5448..759bde32 100644 --- a/src/driver/net/proto/driver.net.proto.tcp.pas +++ b/src/driver/net/proto/driver.net.proto.tcp.pas @@ -40,8 +40,8 @@ procedure terminal_command_tcphttp(params : PParamList; stdin_buf, stdout_buf, s implementation uses - memory.heap, core.util, arch.x86.util, io.syslog, core.rand, core.ds.lists, - driver.net, arch.x86.isr.tmr0, arch.x86.bda, + memory.heap, core.util, arch.platform.cpu, io.syslog, core.rand, core.ds.lists, + driver.net, arch.platform.interrupts, arch.common.legacyirq, core.strings, driver.net.proto.arp, proc.mgr, proc.types; @@ -79,6 +79,10 @@ const var Connections : PDList; Registered : Boolean = false; + TimerFraction: uint32; + +type + PPtrUInt = ^PtrUInt; { ============================================================================ } { Utility: TCP Flag Helpers } @@ -120,16 +124,16 @@ begin pseudoSize := pseudoSize + 1; pseudoBuf := kalloc(pseudoSize); - memset(uint32(pseudoBuf), 0, pseudoSize); + memset(PtrUInt(pseudoBuf), 0, pseudoSize); pseudoHdr := PTCPPseudoHeader(pseudoBuf); - memcpy(uint32(srcIP), uint32(@pseudoHdr^.Source_IP), 4); - memcpy(uint32(dstIP), uint32(@pseudoHdr^.Destination_IP), 4); + memcpy(PtrUInt(srcIP), PtrUInt(@pseudoHdr^.Source_IP), 4); + memcpy(PtrUInt(dstIP), PtrUInt(@pseudoHdr^.Destination_IP), 4); pseudoHdr^.Reserved := 0; pseudoHdr^.Protocol := TCP_PROTOCOL_ID; pseudoHdr^.TCP_Length := switchendian16(tcpLen); - memcpy(uint32(tcpData), uint32(pseudoBuf) + sizeof(TTCPPseudoHeader), tcpLen); + memcpy(PtrUInt(tcpData), PtrUInt(pseudoBuf) + sizeof(TTCPPseudoHeader), tcpLen); { Compute one's complement sum } sum := 0; @@ -160,7 +164,7 @@ var begin push_trace('driver.net.proto.tcp.CreateTCB'); tcb := PTCB(kalloc(sizeof(TTCB))); - memset(uint32(tcb), 0, sizeof(TTCB)); + memset(PtrUInt(tcb), 0, sizeof(TTCB)); tcb^.State := tssClosed; tcb^.RCV_WND := TCP_DEFAULT_WINDOW; tcb^.SendBufSize := TCP_DEFAULT_WINDOW; @@ -299,7 +303,7 @@ begin for i := 0 to DL_Size(Connections) - 1 do begin p := DL_Get(Connections, i); if p <> nil then begin - tcb := PTCB(puint32(p)^); + tcb := PTCB(PPtrUInt(p)^); if tcb <> nil then begin if tcb^.Active then begin if (tcb^.LocalPort = localPort) and @@ -326,7 +330,7 @@ begin for i := 0 to DL_Size(Connections) - 1 do begin p := DL_Get(Connections, i); if p <> nil then begin - tcb := PTCB(puint32(p)^); + tcb := PTCB(PPtrUInt(p)^); if tcb <> nil then begin if tcb^.Active and (tcb^.State = tssListen) and (tcb^.LocalPort = localPort) then begin FindListenTCB := tcb; @@ -339,13 +343,13 @@ end; procedure AddTCB(tcb : PTCB); var - p : puint32; + p : PPtrUInt; begin push_trace('driver.net.proto.tcp.AddTCB'); if Connections = nil then - Connections := DL_New(sizeof(uint32)); - p := puint32(DL_Add(Connections)); - p^ := uint32(tcb); + Connections := DL_New(sizeof(PtrUInt)); + p := PPtrUInt(DL_Add(Connections)); + p^ := PtrUInt(tcb); end; procedure RemoveTCB(tcb : PTCB); @@ -359,7 +363,7 @@ begin for i := 0 to DL_Size(Connections) - 1 do begin p := DL_Get(Connections, i); if p <> nil then begin - cur := PTCB(puint32(p)^); + cur := PTCB(PPtrUInt(p)^); if cur = tcb then begin DL_Delete(Connections, i); exit; @@ -406,7 +410,7 @@ begin for i := 0 to DL_Size(Connections) - 1 do begin p := DL_Get(Connections, i); if p <> nil then begin - tcb := PTCB(puint32(p)^); + tcb := PTCB(PPtrUInt(p)^); if (tcb <> nil) and tcb^.Active and (tcb^.LocalPort = localPort) and (tcb^.State = tssSynReceived) then @@ -429,7 +433,7 @@ begin for i := 0 to DL_Size(Connections) - 1 do begin p := DL_Get(Connections, i); if p <> nil then begin - tcb := PTCB(puint32(p)^); + tcb := PTCB(PPtrUInt(p)^); if (tcb <> nil) and tcb^.Active and (tcb^.LocalPort = localPort) and (tcb^.State = tssEstablished) and @@ -522,7 +526,7 @@ begin if not tcb^.OOOSegments[i].Valid then begin tcb^.OOOSegments[i].SeqNum := seqNum; tcb^.OOOSegments[i].Data := kalloc(payloadLen); - memcpy(uint32(payload), uint32(tcb^.OOOSegments[i].Data), payloadLen); + memcpy(PtrUInt(payload), PtrUInt(tcb^.OOOSegments[i].Data), payloadLen); tcb^.OOOSegments[i].DataLen := payloadLen; tcb^.OOOSegments[i].Valid := true; exit; @@ -541,7 +545,7 @@ begin kfree(tcb^.OOOSegments[oldIdx].Data); tcb^.OOOSegments[oldIdx].SeqNum := seqNum; tcb^.OOOSegments[oldIdx].Data := kalloc(payloadLen); - memcpy(uint32(payload), uint32(tcb^.OOOSegments[oldIdx].Data), payloadLen); + memcpy(PtrUInt(payload), PtrUInt(tcb^.OOOSegments[oldIdx].Data), payloadLen); tcb^.OOOSegments[oldIdx].DataLen := payloadLen; tcb^.OOOSegments[oldIdx].Valid := true; end; @@ -566,8 +570,8 @@ begin if copyLen > (tcb^.RecvBufSize - tcb^.RecvBufLen) then copyLen := tcb^.RecvBufSize - tcb^.RecvBufLen; if copyLen > 0 then begin - memcpy(uint32(tcb^.OOOSegments[i].Data), - uint32(tcb^.RecvBuf) + tcb^.RecvBufLen, copyLen); + memcpy(PtrUInt(tcb^.OOOSegments[i].Data), + PtrUInt(tcb^.RecvBuf) + tcb^.RecvBufLen, copyLen); tcb^.RecvBufLen := tcb^.RecvBufLen + copyLen; tcb^.RCV_NXT := tcb^.RCV_NXT + copyLen; tcb^.RCV_WND := tcb^.RecvBufSize - tcb^.RecvBufLen; @@ -611,7 +615,7 @@ begin totalLen := hdrLen + payloadLen; buffer := kalloc(totalLen); - memset(uint32(buffer), 0, totalLen); + memset(PtrUInt(buffer), 0, totalLen); hdr := PTCPHeader(buffer); hdr^.SrcPort := switchendian16(tcb^.LocalPort); @@ -623,7 +627,7 @@ begin { Data offset = 6 (24 bytes), includes MSS option } hdr^.DataOff_Flags := switchendian16(MakeDataOffFlags(6, flags)); { Write MSS option after 20-byte header: Kind=2, Len=4, MSS } - opts := puint8(uint32(buffer) + sizeof(TTCPHeader)); + opts := puint8(PtrUInt(buffer) + sizeof(TTCPHeader)); opts[0] := TCP_MSS_OPT_KIND; opts[1] := TCP_MSS_OPT_LEN; opts[2] := uint8(TCP_DEFAULT_MSS SHR 8); @@ -637,7 +641,7 @@ begin hdr^.UrgentPtr := 0; if (payload <> nil) and (payloadLen > 0) then - memcpy(uint32(payload), uint32(buffer) + hdrLen, payloadLen); + memcpy(PtrUInt(payload), PtrUInt(buffer) + hdrLen, payloadLen); { Calculate checksum } chk := CalculateChecksum(buffer, totalLen, @tcb^.LocalIP[0], @tcb^.RemoteIP[0]); @@ -666,7 +670,7 @@ begin tcb^.RTTMeasuring := true; tcb^.RTTSeqNum := tcb^.SND_NXT + payloadLen; if isSYN then tcb^.RTTSeqNum := tcb^.SND_NXT + 1; - tcb^.RTTStartTime := Counters.c32; + tcb^.RTTStartTime := networkTicks; end; { Reset keep-alive timer on any send } @@ -681,11 +685,11 @@ begin if ((flags AND (TCP_FLAG_SYN OR TCP_FLAG_FIN)) <> 0) or (payloadLen > 0) then begin if tcb^.RetransBuf <> nil then kfree(tcb^.RetransBuf); tcb^.RetransBuf := kalloc(totalLen); - memcpy(uint32(buffer), uint32(tcb^.RetransBuf), totalLen); + memcpy(PtrUInt(buffer), PtrUInt(tcb^.RetransBuf), totalLen); tcb^.RetransBufLen := totalLen; tcb^.RetransTimer := tcb^.RTO; { Use adaptive RTO } tcb^.RetransCount := 0; - tcb^.LastSendTime := Counters.c32; + tcb^.LastSendTime := networkTicks; end; freePacketContext(context); @@ -701,7 +705,7 @@ var begin push_trace('driver.net.proto.tcp.SendRST'); buffer := kalloc(sizeof(TTCPHeader)); - memset(uint32(buffer), 0, sizeof(TTCPHeader)); + memset(PtrUInt(buffer), 0, sizeof(TTCPHeader)); hdr.SrcPort := switchendian16(localPort); hdr.DstPort := switchendian16(remotePort); @@ -712,7 +716,7 @@ begin hdr.Checksum := 0; hdr.UrgentPtr := 0; - memcpy(uint32(@hdr), uint32(buffer), sizeof(TTCPHeader)); + memcpy(PtrUInt(@hdr), PtrUInt(buffer), sizeof(TTCPHeader)); chk := CalculateChecksum(buffer, sizeof(TTCPHeader), localIP, remoteIP); PTCPHeader(buffer)^.Checksum := chk; @@ -760,7 +764,7 @@ begin { Parse options pointer } if dataOff > 5 then begin - optsPtr := puint8(uint32(hdr) + sizeof(TTCPHeader)); + optsPtr := puint8(PtrUInt(hdr) + sizeof(TTCPHeader)); optsLen := (dataOff - 5) * 4; end else begin optsPtr := nil; @@ -797,7 +801,7 @@ begin { RTT measurement complete } if tcb^.RTTMeasuring then begin - rttSample := Counters.c32 - tcb^.RTTStartTime; + rttSample := networkTicks - tcb^.RTTStartTime; if rttSample > 0 then UpdateRTT(tcb, rttSample); tcb^.RTTMeasuring := false; @@ -854,7 +858,7 @@ begin { RTT measurement } if tcb^.RTTMeasuring then begin - rttSample := Counters.c32 - tcb^.RTTStartTime; + rttSample := networkTicks - tcb^.RTTStartTime; if rttSample > 0 then UpdateRTT(tcb, rttSample); tcb^.RTTMeasuring := false; @@ -890,7 +894,7 @@ begin { RTT measurement: complete if ACK covers timed segment } if tcb^.RTTMeasuring and (ackNum >= tcb^.RTTSeqNum) then begin - rttSample := Counters.c32 - tcb^.RTTStartTime; + rttSample := networkTicks - tcb^.RTTStartTime; if rttSample > 0 then UpdateRTT(tcb, rttSample); tcb^.RTTMeasuring := false; @@ -939,8 +943,8 @@ begin tcb^.SND_NXT := tcb^.SND_NXT + copyLen; { Shift remaining data in send buffer } if copyLen < tcb^.SendBufLen then begin - memcpy(uint32(tcb^.SendBuf) + copyLen, - uint32(tcb^.SendBuf), + memcpy(PtrUInt(tcb^.SendBuf) + copyLen, + PtrUInt(tcb^.SendBuf), tcb^.SendBufLen - copyLen); end; tcb^.SendBufLen := tcb^.SendBufLen - copyLen; @@ -963,7 +967,7 @@ begin copyLen := tcb^.RecvBufSize - tcb^.RecvBufLen; if copyLen > 0 then begin - memcpy(uint32(payload), uint32(tcb^.RecvBuf) + tcb^.RecvBufLen, copyLen); + memcpy(PtrUInt(payload), PtrUInt(tcb^.RecvBuf) + tcb^.RecvBufLen, copyLen); tcb^.RecvBufLen := tcb^.RecvBufLen + copyLen; tcb^.RCV_NXT := tcb^.RCV_NXT + copyLen; tcb^.RCV_WND := tcb^.RecvBufSize - tcb^.RecvBufLen; @@ -1164,7 +1168,7 @@ begin { Parse MSS option from SYN } if dataOff > 5 then begin - optsPtr := puint8(uint32(p_data) + sizeof(TTCPHeader)); + optsPtr := puint8(PtrUInt(p_data) + sizeof(TTCPHeader)); optsLen := (dataOff - 5) * 4; mss := ParseMSSOption(optsPtr, optsLen); if mss > 0 then @@ -1217,6 +1221,9 @@ var count : uint32; effMSS : uint16; begin + TimerFraction := TimerFraction + PIT_DIVISOR * 1024; + if TimerFraction < PIT_INPUT_HZ then exit; + TimerFraction := TimerFraction - PIT_INPUT_HZ; if Connections = nil then exit; count := DL_Size(Connections); if count = 0 then exit; @@ -1225,7 +1232,7 @@ begin while i < count do begin p := DL_Get(Connections, i); if p <> nil then begin - tcb := PTCB(puint32(p)^); + tcb := PTCB(PPtrUInt(p)^); if (tcb <> nil) and tcb^.Active then begin { Delayed ACK timer } @@ -1422,7 +1429,7 @@ begin if tcb = nil then exit; copyIPv4(@getIPv4Config^.Address[0], @tcb^.LocalIP[0]); - memset(uint32(@tcb^.RemoteIP[0]), 0, 4); + memset(PtrUInt(@tcb^.RemoteIP[0]), 0, 4); tcb^.LocalPort := context^.LocalPort; tcb^.RemotePort := 0; tcb^.State := tssListen; @@ -1503,7 +1510,7 @@ begin if copyLen > (tcb^.SendBufSize - tcb^.SendBufLen) then copyLen := tcb^.SendBufSize - tcb^.SendBufLen; if copyLen > 0 then begin - memcpy(uint32(p_data), uint32(tcb^.SendBuf) + tcb^.SendBufLen, copyLen); + memcpy(PtrUInt(p_data), PtrUInt(tcb^.SendBuf) + tcb^.SendBufLen, copyLen); tcb^.SendBufLen := tcb^.SendBufLen + copyLen; end; send := tteOK; @@ -1523,7 +1530,7 @@ begin if copyLen > (tcb^.SendBufSize - tcb^.SendBufLen) then copyLen := tcb^.SendBufSize - tcb^.SendBufLen; if copyLen > 0 then begin - memcpy(uint32(p_data), uint32(tcb^.SendBuf) + tcb^.SendBufLen, copyLen); + memcpy(PtrUInt(p_data), PtrUInt(tcb^.SendBuf) + tcb^.SendBufLen, copyLen); tcb^.SendBufLen := tcb^.SendBufLen + copyLen; end; send := tteOK; @@ -1867,7 +1874,7 @@ begin port := uint16(stringToInt(getParam(1, params))); { Store host string for HTTP Host header } - memset(uint32(@TCPHTTP_Host[0]), 0, 64); + memset(PtrUInt(@TCPHTTP_Host[0]), 0, 64); i := 0; while (ip_str[i] <> #0) and (i < 63) do begin TCPHTTP_Host[i] := ip_str[i]; @@ -1900,12 +1907,12 @@ begin push_trace('driver.net.proto.tcp.register'); writeToLogLn(' L4/TCP: register'); if not Registered then begin - Connections := DL_New(sizeof(uint32)); + Connections := DL_New(sizeof(PtrUInt)); driver.net.proto.ipv4.registerProtocol(TCP_PROTOCOL_ID, @ProcessPacket); - arch.x86.isr.tmr0.hook(uint32(@TimerTick)); + arch.platform.interrupts.registerTimer(@TimerTick); Registered := true; io.syslog.logln('TCP', 'TCP registered.'); end; end; -end. \ No newline at end of file +end. diff --git a/src/driver/net/proto/driver.net.proto.udp.pas b/src/driver/net/proto/driver.net.proto.udp.pas index 3f1ab4ed..b3719fd5 100644 --- a/src/driver/net/proto/driver.net.proto.udp.pas +++ b/src/driver/net/proto/driver.net.proto.udp.pas @@ -25,7 +25,7 @@ uses memory.heap, driver.net.types, driver.net.util, driver.net.proto.ipv4, driver.net, - debug.tracer, core.util, arch.x86.util; + debug.tracer, core.util, arch.platform.cpu; procedure register(); function bind(bindContext : PUDPBindContext) : TUDPError; @@ -83,7 +83,7 @@ begin pseudoHeader^.UDP_Source:= pseduoSrc; pseudoHeader^.UDP_Destination:= udpContext^.DstPort; pseudoHeader^.UDP_Length:= size; - memcpy(uint32(p_data), uint32(pseudoBuffer) + SizeOf(TUDPPseudoHeader), p_len); + memcpy(PtrUInt(p_data), PtrUInt(pseudoBuffer) + SizeOf(TUDPPseudoHeader), p_len); if nullend then pseudoBuffer8[pseudoSize-1]:= 0; pseudoHeader^.Source_IP:= switchendian32(pseudoHeader^.Source_IP); @@ -136,8 +136,8 @@ begin hdr^.Checksum:= switchendian16(checksum); hdr^.Length:= switchendian16(size); - memcpy(uint32(hdr), uint32(buffer), sizeof(TUDPHeader)); - memcpy(uint32(p_data), uint32(buffer) + sizeof(TUDPHeader), p_len); + memcpy(PtrUInt(hdr), PtrUInt(buffer), sizeof(TUDPHeader)); + memcpy(PtrUInt(p_data), PtrUInt(buffer) + sizeof(TUDPHeader), p_len); udpContext^.context^.Protocol.L4:= $11; @@ -208,7 +208,10 @@ var begin push_trace('driver.net.proto.udp.ProcessPacket'); + if (p_data = nil) or (p_len < sizeof(TUDPHeader)) then exit; header:= PUDPHeader(p_data); + size := switchendian16(header^.Length); + if (size < sizeof(TUDPHeader)) or (size > p_len) then exit; if Ports[switchendian16(header^.DstPort)] <> nil then begin context:= PUDPPacketContext(kalloc(sizeof(TUDPPacketContext))); context^.PacketContext:= p_context; @@ -272,4 +275,4 @@ begin driver.net.proto.ipv4.registerProtocol($11, @ProcessPacket); end; -end. \ No newline at end of file +end.