From 0248ab2a90d5f572c6f738d03e7319a9c50d8cfc Mon Sep 17 00:00:00 2001 From: kieron Date: Tue, 7 Jul 2020 22:52:42 +0000 Subject: [PATCH] UDP Implemented. git-svn-id: https://spexeah.com:8443/svn/Asuro@818 6dbc8c32-bb84-406f-8558-d1cf31a0ab0c --- src/driver/net/include/nettypes.pas | 26 ++++++ src/driver/net/l1/net.pas | 3 +- src/driver/net/l4/udp.pas | 119 +++++++++++++++++++++++++++- src/include/util.pas | 6 ++ 4 files changed, 152 insertions(+), 2 deletions(-) diff --git a/src/driver/net/include/nettypes.pas b/src/driver/net/include/nettypes.pas index ddda921f..43d03577 100644 --- a/src/driver/net/include/nettypes.pas +++ b/src/driver/net/include/nettypes.pas @@ -148,6 +148,32 @@ type Options : uint32; end; + { UDP } + TUDPError = (tueOK, tuePortInUse, tuePortRestricted, tuePortNotFound, tueInvalidUID, tueGenericError); + PUDPPacketContext = ^TUDPPacketContext; + TUDPRecieveCallback = procedure(p_data : void; p_len : uint16; context : PUDPPacketContext); + TUDPPacketContext = record + SrcPort : Word; + DstPort : Word; + ChecksumValid : Boolean; + Length : uint16; + PacketContext : PPacketContext; + end; + PUDPBindContext = ^TUDPBindContext; + TUDPBindContext = record + Port : uint16; + Callback : TUDPRecieveCallback; + UID : uint32; + end; + PUDPHeader = ^TUDPHeader; + TUDPHeader = bitpacked record + SrcPort : Word; + DstPort : Word; + Length : Word; + Checksum : Word; + end; + + { Callback Types } TNetSendCallback = function(p_data : void; p_len : uint16) : sint32; diff --git a/src/driver/net/l1/net.pas b/src/driver/net/l1/net.pas index 330f07f0..6a29330d 100644 --- a/src/driver/net/l1/net.pas +++ b/src/driver/net/l1/net.pas @@ -26,7 +26,7 @@ procedure writeToLogLn(str : pchar); implementation uses - ipv4, arp, eth2, icmp, e1000, terminal; + ipv4, arp, eth2, icmp, e1000, terminal, udp; var CBSend : TNetSendCallback = nil; @@ -120,6 +120,7 @@ begin arp.register; ipv4.register; icmp.register; + udp.register; pop_trace; end; diff --git a/src/driver/net/l4/udp.pas b/src/driver/net/l4/udp.pas index d4181618..98f1f276 100644 --- a/src/driver/net/l4/udp.pas +++ b/src/driver/net/l4/udp.pas @@ -8,9 +8,126 @@ unit udp; interface uses + lmemorymanager, nettypes, netutils, - ipv4; + ipv4, netlog, net, + util; + +var + Ports : Array[0..65535] of PUDPBindContext; + +procedure register(); implementation +uses + console, terminal; + +function bind(bindContext : PUDPBindContext) : TUDPError; +var + result : TUDPError; + context : PUDPBindContext; + +begin + result:= tueGenericError; + if bindContext <> nil then begin + if Ports[bindContext^.port] = nil then begin + context:= PUDPBindContext(kalloc(sizeof(TUDPBindContext))); + context^.Port:= bindContext^.port; + context^.Callback:= bindContext^.Callback; + context^.UID:= bindContext^.UID; + Ports[context^.Port]:= context; + result:= tueOK; + end else begin + result:= tuePortInUse; + end; + end; + bind:= result; +end; + +function unbind(bindContext : PUDPBindContext) : TUDPError; +var + result : TUDPError; + context : PUDPBindContext; + +begin + result:= tueGenericError; + if bindContext <> nil then begin + context:= Ports[bindContext^.port]; + if Ports[bindContext^.port] <> nil then begin + if context^.UID = bindContext^.UID then begin + kfree(void(context)); + Ports[bindContext^.port]:= nil; + result:= tueOK; + end else begin + result:= tueInvalidUID; + end; + end else begin + result:= tuePortNotFound; + end; + end; +end; + +procedure UDPReceive(p_data : void; p_len : uint16; p_context : PPacketContext); +var + header : PUDPHeader; + context : PUDPPacketContext; + buf : puint8; + bind : PUDPBindContext; + +begin + writeToLogLn(' L4: udp.recv'); + header:= PUDPHeader(p_data); + if switchendian16(header^.SrcPort) = 22294 then WriteStringln('Src-E: 22294'); + if header^.SrcPort = 22294 then WriteStringln('Src: 22294'); + if switchendian16(header^.DstPort) = 22294 then WriteStringln('Dst-E: 22294'); + if header^.DstPort = 22294 then WriteStringln('Dst: 22294'); + if Ports[header^.DstPort] <> nil then begin + bind:= Ports[header^.DstPort]; + context:= PUDPPacketContext(kalloc(sizeof(TUDPPacketContext))); + context^.PacketContext:= p_context; + context^.SrcPort:= header^.SrcPort; + context^.DstPort:= header^.DstPort; + context^.ChecksumValid:= false; + context^.Length:= header^.Length; + buf:= puint8(p_data); + buf:= buf + (sizeof(TUDPHeader)); + bind^.Callback(void(buf), context^.Length, context); + end; +end; + +procedure TestRecv(p_data : void; p_len : uint16; context : PUDPPacketContext); +var + Output : PChar; + +begin + Output:= PChar(kalloc(p_len+1)); + memcpy(uint32(p_data), uint32(Output), p_len); + Output[p_len+1]:= Char(0); + Writestringln(Output); +end; + +procedure register(); +var + i : uint16; + context : TUDPBindContext; + r : TUDPError; + +begin + for i:=0 to 65535 do begin + Ports[i]:= nil; + end; + context.Port:= 22294; + context.Callback:= @TestRecv; + context.UID:= 4398724; + r:= bind(@context); + case r of + tueOK:writestringln('22294 bind OK'); + tuePortInUse:writestringln('22294 port in use'); + tueGenericError:writestringln('22294 generic error'); + tuePortRestricted:writestringln('22294 restricted'); + end; + ipv4.registerProtocol($11, @UDPReceive); +end; + end. \ No newline at end of file diff --git a/src/include/util.pas b/src/include/util.pas index f9ad8038..72b399c4 100644 --- a/src/include/util.pas +++ b/src/include/util.pas @@ -20,6 +20,7 @@ procedure GPF(); function hi(b : uint8) : uint8; function lo(b : uint8) : uint8; function switchendian(b : uint8) : uint8; +function switchendian16(b : uint16) : uint16; function switchendian32(b : uint32) : uint32; function getWord(i : uint32; hi : boolean) : uint16; function getByte(i : uint32; index : uint8) : uint8; @@ -97,6 +98,11 @@ begin div6432:= (r0 SHL 32) OR r4; end; +function switchendian16(b : uint16) : uint16; +begin + switchendian16:= ((b AND $FF00) SHR 8) OR ((b AND $00FF) SHR 8); +end; + function switchendian32(b : uint32) : uint32; begin switchendian32:= ((b AND $FF000000) SHR 24) OR