diff -uNr a/udp/README b/udp/README
--- a/udp/README false
+++ b/udp/README eeb9a58cb91ed01f00b5c977af8b546ca8112229987c12460d3832b0787a673edd72ea2f4d1138892eb013f4136058a68ee3e5de22a754d9a45b4e0dab5433ce
@@ -0,0 +1,7 @@
+cd echodemo
+gprbuild
+
+cd txdemo
+gprbuild
+
+see demo code for instructions, it is self-explanatory.
diff -uNr a/udp/echodemo/bin/README b/udp/echodemo/bin/README
--- a/udp/echodemo/bin/README false
+++ b/udp/echodemo/bin/README 5fdbae897eb301a711bf95707f329517db540e34c182a5beec96e93d5d0d856cec2ed6b01c1191f865e8d1c45709a462c70c3005d4aa3676eb445d1479edf2e5
@@ -0,0 +1 @@
+Placeholder.
diff -uNr a/udp/echodemo/obj/README b/udp/echodemo/obj/README
--- a/udp/echodemo/obj/README false
+++ b/udp/echodemo/obj/README 5fdbae897eb301a711bf95707f329517db540e34c182a5beec96e93d5d0d856cec2ed6b01c1191f865e8d1c45709a462c70c3005d4aa3676eb445d1479edf2e5
@@ -0,0 +1 @@
+Placeholder.
diff -uNr a/udp/echodemo/udp_echo_demo.adb b/udp/echodemo/udp_echo_demo.adb
--- a/udp/echodemo/udp_echo_demo.adb false
+++ b/udp/echodemo/udp_echo_demo.adb 8338a018f49bee220073e50372407c6a47e2cd77847aec8c73734dd0dc7060e750a5df4306b8d955c220d49560926987dab99b35615f5e5c7721d818ec0fac22
@@ -0,0 +1,69 @@
+------------------------------------------------------------------------------
+------------------------------------------------------------------------------
+-- This file is part of 'UDP Echo Demo', accompanies 'UDP' library.         --
+--                                                                          --
+-- (C) 2018 Stanislav Datskovskiy ( www.loper-os.org )                      --
+-- http://wot.deedbot.org/17215D118B7239507FAFED98B98228A001ABFFC7.html     --
+--                                                                          --
+-- You do not have, nor can you ever acquire the right to use, copy or      --
+-- distribute this software ; Should you use this software for any purpose, --
+-- or copy and distribute it to anyone or in any manner, you are breaking   --
+-- the laws of whatever soi-disant jurisdiction, and you promise to         --
+-- continue doing so for the indefinite future. In any case, please         --
+-- always : read and understand any software ; verify any PGP signatures    --
+-- that you use - for any purpose.                                          --
+--                                                                          --
+-- See also http://trilema.com/2015/a-new-software-licensing-paradigm .     --
+------------------------------------------------------------------------------
+------------------------------------------------------------------------------
+
+with Ada.Text_IO; use Ada.Text_IO;
+
+with UDP;
+
+
+procedure UDP_Echo_Demo is
+   
+   Socket           : UDP.Socket;
+   
+   --  Local_Endpoint   : UDP.Endpoint
+   --    := (Address => UDP.IP_From_String("127.0.0.1"),
+   --        Port    => 7000);
+   
+   Local_Endpoint   : UDP.Endpoint := (Address => UDP.INADDR_ANY,
+                                       Port    => 7000);
+   
+   Received_Payload : UDP.Payload;
+   Received_Origin  : UDP.Endpoint;
+   Received_Valid   : Boolean;
+   
+begin
+   Put_Line("Opening socket on local endpoint " &
+              UDP.IP_To_String(Local_Endpoint.Address) &
+              " :" & UDP.IP_Port'Image(Local_Endpoint.Port) & "...");
+   
+   UDP.Open_Socket(Socket, Local_Endpoint);
+   
+   Put_Line("Waiting for payload...");
+   
+   UDP.Receive(Socket, Received_Origin, Received_Payload, Received_Valid);
+   
+   Put_Line("Received payload from " &
+              UDP.IP_To_String(Received_Origin.Address) &
+              " :" & UDP.IP_Port'Image(Received_Origin.Port) & "...");
+   
+   if Received_Valid then
+      
+      Put_Line("Sending received payload back to originator...");
+      
+      UDP.Transmit(Socket, Received_Origin, Received_Payload);
+      
+   else
+      
+      Put_Line("Received short payload, ignored.");
+      
+   end if;
+   
+   Put_Line("Done.");
+
+end UDP_Echo_Demo;
diff -uNr a/udp/echodemo/udp_echo_demo.gpr b/udp/echodemo/udp_echo_demo.gpr
--- a/udp/echodemo/udp_echo_demo.gpr false
+++ b/udp/echodemo/udp_echo_demo.gpr 685962341177af7f4e42e4145699b2c85875fcb1b30095a71f86346d4c844aee4e30dd756394a2c41ce75ce2367ac89e9549b84f9bdf5a73673a488d3b53892b
@@ -0,0 +1,69 @@
+------------------------------------------------------------------------------
+------------------------------------------------------------------------------
+-- This file is part of 'UDP Echo Demo', accompanies 'UDP' library.         --
+--                                                                          --
+-- (C) 2018 Stanislav Datskovskiy ( www.loper-os.org )                      --
+-- http://wot.deedbot.org/17215D118B7239507FAFED98B98228A001ABFFC7.html     --
+--                                                                          --
+-- You do not have, nor can you ever acquire the right to use, copy or      --
+-- distribute this software ; Should you use this software for any purpose, --
+-- or copy and distribute it to anyone or in any manner, you are breaking   --
+-- the laws of whatever soi-disant jurisdiction, and you promise to         --
+-- continue doing so for the indefinite future. In any case, please         --
+-- always : read and understand any software ; verify any PGP signatures    --
+-- that you use - for any purpose.                                          --
+--                                                                          --
+-- See also http://trilema.com/2015/a-new-software-licensing-paradigm .     --
+------------------------------------------------------------------------------
+------------------------------------------------------------------------------
+
+with "../libudp/udp.gpr";
+
+project UDP_Echo_Demo is
+  
+  for Object_Dir use "obj";
+  
+  type Mode_Type is ("debug", "release");
+  Mode : Mode_Type := external ("mode", "release");
+  
+  for Languages   use ("Ada");
+  for Source_Dirs use (".");
+  for Exec_Dir    use "bin";
+  for Main        use ("udp_echo_demo.adb");
+  
+  package Compiler is
+     case Mode is
+        when "debug" =>
+           for Switches ("Ada")
+             use ("-g");
+        when "release" =>
+           for Switches ("Ada")
+             use ("-O2", "-fdump-scos", "-gnata", "-fstack-check",
+                  "-gnatyd", "-gnatym",
+                  "-fdata-sections", "-ffunction-sections");
+     end case;
+  end Compiler;
+  
+  package Binder is
+     case Mode is
+        when "debug" =>
+           for Switches ("Ada")
+             use ();
+        when "release" =>
+           for Switches ("Ada")
+             use ("-static");
+     end case;
+  end Binder;
+
+  package Linker is
+     case Mode is
+        when "debug" =>
+           for Switches ("Ada")
+             use ();
+        when "release" =>
+           for Switches ("Ada")
+             use ("-Wl,--gc-sections", "-static");
+     end case;
+  end Linker;
+  
+end UDP_Echo_Demo;
diff -uNr a/udp/libudp/lib/README b/udp/libudp/lib/README
--- a/udp/libudp/lib/README false
+++ b/udp/libudp/lib/README 5fdbae897eb301a711bf95707f329517db540e34c182a5beec96e93d5d0d856cec2ed6b01c1191f865e8d1c45709a462c70c3005d4aa3676eb445d1479edf2e5
@@ -0,0 +1 @@
+Placeholder.
diff -uNr a/udp/libudp/obj/README b/udp/libudp/obj/README
--- a/udp/libudp/obj/README false
+++ b/udp/libudp/obj/README 5fdbae897eb301a711bf95707f329517db540e34c182a5beec96e93d5d0d856cec2ed6b01c1191f865e8d1c45709a462c70c3005d4aa3676eb445d1479edf2e5
@@ -0,0 +1 @@
+Placeholder.
diff -uNr a/udp/libudp/restrict.adc b/udp/libudp/restrict.adc
--- a/udp/libudp/restrict.adc false
+++ b/udp/libudp/restrict.adc 68ce604c3473b8e39860974754a353618ba8f1f34a3038c111d0cf64e4558a9bc909f63368bf71d076c4895129ac2efb5f44e27f03b7fb38d515acd4e6da2e62
@@ -0,0 +1,82 @@
+------------------------------------------------------------------------------
+------------------------------------------------------------------------------
+-- This file is part of 'UDP', a datagram sockets library.                  --
+--                                                                          --
+-- (C) 2018 Stanislav Datskovskiy ( www.loper-os.org )                      --
+-- http://wot.deedbot.org/17215D118B7239507FAFED98B98228A001ABFFC7.html     --
+--                                                                          --
+-- You do not have, nor can you ever acquire the right to use, copy or      --
+-- distribute this software ; Should you use this software for any purpose, --
+-- or copy and distribute it to anyone or in any manner, you are breaking   --
+-- the laws of whatever soi-disant jurisdiction, and you promise to         --
+-- continue doing so for the indefinite future. In any case, please         --
+-- always : read and understand any software ; verify any PGP signatures    --
+-- that you use - for any purpose.                                          --
+--                                                                          --
+-- See also http://trilema.com/2015/a-new-software-licensing-paradigm .     --
+------------------------------------------------------------------------------
+------------------------------------------------------------------------------
+
+pragma Restrictions(Immediate_Reclamation);
+pragma Restrictions(Max_Asynchronous_Select_Nesting => 0);
+pragma Restrictions(Max_Protected_Entries => 0);
+pragma Restrictions(Max_Select_Alternatives => 0);
+pragma Restrictions(Max_Task_Entries => 0);
+pragma Restrictions(Max_Tasks => 0);
+pragma Restrictions(No_Abort_Statements);
+pragma Restrictions(No_Access_Parameter_Allocators);
+pragma Restrictions(No_Allocators);
+pragma Restrictions(No_Asynchronous_Control);
+pragma Restrictions(No_Calendar);
+pragma Restrictions(No_Coextensions);
+pragma Restrictions(No_Default_Stream_Attributes);
+pragma Restrictions(No_Delay);
+pragma Restrictions(No_Dispatch);
+pragma Restrictions(No_Dispatching_Calls);
+pragma Restrictions(No_Dynamic_Attachment);
+pragma Restrictions(No_Dynamic_Priorities);
+pragma Restrictions(No_Entry_Calls_In_Elaboration_Code);
+pragma Restrictions(No_Entry_Queue);
+pragma Restrictions(No_Enumeration_Maps);
+pragma Restrictions(No_Exception_Propagation);
+pragma Restrictions(No_Exception_Registration);
+pragma Restrictions(No_Finalization);
+pragma Restrictions(No_Fixed_Io);
+pragma Restrictions(No_Floating_Point);
+pragma Restrictions(No_Implementation_Aspect_Specifications);
+pragma Restrictions(No_Implementation_Units);
+pragma Restrictions(No_Implicit_Dynamic_Code);
+pragma Restrictions(No_Implicit_Heap_Allocations);
+pragma Restrictions(No_Implicit_Protected_Object_Allocations);
+pragma Restrictions(No_Implicit_Task_Allocations);
+pragma Restrictions(No_Initialize_Scalars);
+pragma Restrictions(No_Local_Protected_Objects);
+pragma Restrictions(No_Local_Timing_Events);
+pragma Restrictions(No_Multiple_Elaboration);
+pragma Restrictions(No_Nested_Finalization);
+pragma Restrictions(No_Protected_Type_Allocators);
+pragma Restrictions(No_Protected_Types);
+pragma Restrictions(No_Relative_Delay);
+pragma Restrictions(No_Requeue_Statements);
+pragma Restrictions(No_Secondary_Stack);
+pragma Restrictions(No_Select_Statements);
+pragma Restrictions(No_Specific_Termination_Handlers);
+pragma Restrictions(No_Standard_Allocators_After_Elaboration);
+pragma Restrictions(No_Stream_Optimizations);
+pragma Restrictions(No_Streams);
+pragma Restrictions(No_Task_Allocators);
+pragma Restrictions(No_Task_At_Interrupt_Priority);
+pragma Restrictions(No_Task_Attributes_Package);
+pragma Restrictions(No_Task_Hierarchy);
+pragma Restrictions(No_Tasking);
+pragma Restrictions(No_Task_Termination);
+pragma Restrictions(No_Terminate_Alternatives);
+pragma Restrictions(No_Unchecked_Access);
+pragma Restrictions(No_Unchecked_Conversion);
+pragma Restrictions(No_Unchecked_Deallocation);
+pragma Restrictions(No_Wide_Characters);
+pragma Restrictions(Pure_Barriers);
+pragma Restrictions(Simple_Barriers);
+pragma Restrictions(Static_Priorities);
+pragma Restrictions(Static_Storage_Size);
+pragma Validity_Checks(ALL_CHECKS);
diff -uNr a/udp/libudp/udp.adb b/udp/libudp/udp.adb
--- a/udp/libudp/udp.adb false
+++ b/udp/libudp/udp.adb 08d9e728f35338aca8cbd7b2d0d1a124f731e286c15df2e65c4d7c9bb6bf750cd44acbb818eca656bfd3402b77927c300693978576622e6e241c2f00824cc7fe
@@ -0,0 +1,139 @@
+------------------------------------------------------------------------------
+------------------------------------------------------------------------------
+-- This file is part of 'UDP', a datagram sockets library.                  --
+--                                                                          --
+-- (C) 2018 Stanislav Datskovskiy ( www.loper-os.org )                      --
+-- http://wot.deedbot.org/17215D118B7239507FAFED98B98228A001ABFFC7.html     --
+--                                                                          --
+-- You do not have, nor can you ever acquire the right to use, copy or      --
+-- distribute this software ; Should you use this software for any purpose, --
+-- or copy and distribute it to anyone or in any manner, you are breaking   --
+-- the laws of whatever soi-disant jurisdiction, and you promise to         --
+-- continue doing so for the indefinite future. In any case, please         --
+-- always : read and understand any software ; verify any PGP signatures    --
+-- that you use - for any purpose.                                          --
+--                                                                          --
+-- See also http://trilema.com/2015/a-new-software-licensing-paradigm .     --
+------------------------------------------------------------------------------
+------------------------------------------------------------------------------
+
+package body UDP is
+   
+   -- Generate a human representation of a (local-endian) IP Address
+   function IP_To_String(IP : in IP_Address) return IP_Address_Text is
+      Text : IP_Address_Text := (others => ' ');
+   begin
+      Unix_UDP_IP_To_String(IP, Text'Address, Text'Length);
+      return Text;
+   end IP_To_String;
+   
+   
+   -- Generate a (local-endian) IP Address from given human representation
+   function IP_From_String(IP_Text : in String) return IP_Address is
+      Text_With_Null : String(1 .. IP_Text'Length + 1);
+      Result : Interfaces.C.Int := 0;
+      IP     : aliased IP_Address;
+   begin
+      -- We can't use To_C because malicious idiots demanded secondary stack.
+      Text_With_Null(IP_Text'Range) := IP_Text;
+      Text_With_Null(Text_With_Null'Last) := Character'Val(0);
+      
+      -- Let unix do the conversion
+      Result := Unix_UDP_String_To_IP(Text_With_Null'Address,
+                                      IP'Access);
+      case Result is
+         when -1 =>
+            raise UDP_Invalid_Text_IP;
+         when others =>
+            return IP;
+      end case;
+   end IP_From_String;
+   
+   
+   -- Open a UDP socket, with the given local endpoint for both TX and RX
+   procedure Open_Socket(S              : out Socket;
+                         Local_Endpoint : in  Endpoint) is
+      Result : constant Interfaces.C.Int :=
+        Unix_UDP_Socket_Open(Socket     => S'Address,
+                             Local_IP   => Local_Endpoint.Address,
+                             Local_Port => Local_Endpoint.Port);
+   begin
+      case Result is
+         when -1 =>
+            raise UDP_Failed_Open;
+         when -2 =>
+            raise UDP_Failed_SetOpt;
+         when -3 =>
+            raise UDP_Failed_Bind;
+         when others =>
+            null;
+      end case;
+   end Open_Socket;
+   
+   
+   -- Permanently close the given open given socket
+   procedure Close_Socket(S : in out Socket) is
+   begin
+      Unix_UDP_Socket_Close(Socket => S'Address);
+   end Close_Socket;
+   
+   
+   -- Transmit the Payload, via Socket, to given Destination
+   procedure Transmit(S           : in out Socket;
+                      Destination : in     Endpoint;
+                      Payload_Buf : in     Payload) is
+      Result : constant Interfaces.C.Int :=
+        Unix_UDP_Socket_Transmit(Socket      => S'Address,
+                                 Remote_IP   => Destination.Address,
+                                 Remote_Port => Destination.Port,
+                                 Payload_Buf => Payload_Buf'Address,
+                                 Payload_Len => Payload'Length);
+   begin
+      case Result is
+         when -1 =>
+            Close_Socket(S);
+            raise UDP_Failed_Transmit;
+         when others =>
+            -- No eggog
+            null;
+      end case;
+   end Transmit;
+   
+   
+   -- Wait (potentially forever!) for a Payload, via Socket; save its Origin
+   procedure Receive(S           : in out Socket;
+                     Origin      : out    Endpoint;
+                     Payload_Buf : out    Payload;
+                     Valid       : out    Boolean) is
+      
+      -- Scratch pad (if not successful, the call has no outputs)
+      Incoming_Payload : aliased Payload := (others => 0);
+      Incoming_IP      : aliased IP_Address;
+      Incoming_Port    : aliased IP_Port;
+      
+      Result : constant Interfaces.C.Int :=
+        Unix_UDP_Socket_Receive(Socket      => S'Address,
+                                Origin_IP   => Incoming_IP'Access,
+                                Origin_Port => Incoming_Port'Access,
+                                Payload_Buf => Incoming_Payload'Address,
+                                Payload_Len => Payload'Length);
+   begin
+      Valid := False;
+      case Result is
+         when -1 =>
+            Close_Socket(S);
+            raise UDP_Failed_Receive;
+         when others =>
+            -- No eggog:
+            Origin.Address := Incoming_IP;
+            Origin.Port    := Incoming_Port;
+            Payload_Buf    := Incoming_Payload;
+            
+            -- Was a full-length payload?
+            if (Result = Payload'Length) then
+               Valid := True;
+            end if;
+      end case;
+   end Receive;
+   
+end UDP;
diff -uNr a/udp/libudp/udp.ads b/udp/libudp/udp.ads
--- a/udp/libudp/udp.ads false
+++ b/udp/libudp/udp.ads e5225e08aad2ecdaa42e10638fff93c70f5756ad293cc7fca22dfb156583dbef132eeaf48eb36b6614637dd22efefb5cfc43fd724456e9e80e39acc1742d157e
@@ -0,0 +1,149 @@
+------------------------------------------------------------------------------
+------------------------------------------------------------------------------
+-- This file is part of 'UDP', a datagram sockets library.                  --
+--                                                                          --
+-- (C) 2018 Stanislav Datskovskiy ( www.loper-os.org )                      --
+-- http://wot.deedbot.org/17215D118B7239507FAFED98B98228A001ABFFC7.html     --
+--                                                                          --
+-- You do not have, nor can you ever acquire the right to use, copy or      --
+-- distribute this software ; Should you use this software for any purpose, --
+-- or copy and distribute it to anyone or in any manner, you are breaking   --
+-- the laws of whatever soi-disant jurisdiction, and you promise to         --
+-- continue doing so for the indefinite future. In any case, please         --
+-- always : read and understand any software ; verify any PGP signatures    --
+-- that you use - for any purpose.                                          --
+--                                                                          --
+-- See also http://trilema.com/2015/a-new-software-licensing-paradigm .     --
+------------------------------------------------------------------------------
+------------------------------------------------------------------------------
+
+with Interfaces, Interfaces.C; use Interfaces, Interfaces.C;
+with System; use System;
+
+
+package UDP is
+   
+   pragma Preelaborate;
+   
+   -- This is subject to debate:
+   Payload_Size : constant Positive := 512;
+   
+   type Payload is array(1 .. Payload_Size) of Unsigned_8;
+   
+   --  type IP_Address is array(1 .. 4) of Unsigned_8;
+   subtype IP_Address is Unsigned_32;
+   subtype IP_Port is Unsigned_16;
+   
+   -- Magic that puts emitter on 'any' local interface
+   INADDR_ANY : constant Unsigned_32 := 0;
+   
+   -- An local or remote address:port
+   type Endpoint is
+      record
+         Address : IP_Address;
+         Port    : IP_Port;
+      end record;
+   -- NOTE that both elements are stored in ~local~ endianness.
+   
+   -- Human Representation of any valid IP Address
+   subtype IP_Address_Text is String(1 .. 15);
+   
+   -- Opaque unix turd that stores a socket's state
+   type Socket is private;
+   
+   -- The public API:
+   
+   -- Generate a human representation of a (local-endian) IP Address
+   function IP_To_String(IP : in IP_Address) return IP_Address_Text;
+   
+   -- Generate a (local-endian) IP Address from given human representation
+   function IP_From_String(IP_Text : in String) return IP_Address;
+   
+   -- Open a UDP socket, with the given local endpoint for both TX and RX
+   procedure Open_Socket(S              : out    Socket;
+                         Local_Endpoint : in     Endpoint);
+   
+   -- Permanently close the given open given socket
+   procedure Close_Socket(S             : in out Socket);
+   
+   -- Transmit the Payload, via Socket, to given Destination
+   procedure Transmit(S           : in out Socket;
+                      Destination : in     Endpoint;
+                      Payload_Buf : in     Payload);
+   
+   -- Wait (potentially forever!) for a Payload, via Socket; save its Origin,
+   -- and whether the received Payload was valid (i.e. expected length):
+   procedure Receive(S           : in out Socket;
+                     Origin      : out    Endpoint;
+                     Payload_Buf : out    Payload;
+                     Valid       : out    Boolean);
+   
+   -- Eggogology:
+   UDP_Invalid_Text_IP : exception;
+   UDP_Failed_Open     : exception;
+   UDP_Failed_SetOpt   : exception;
+   UDP_Failed_Bind     : exception;
+   UDP_Failed_Transmit : exception;
+   UDP_Failed_Receive  : exception;
+   
+private
+   
+   -- 'nicht fuer gefingerpoken und mittengrabben!'
+   
+   -- This record's elements are not accessed from ada:
+   type sockaddr_in is record
+      family   : Unsigned_16;
+      port     : Unsigned_16;
+      sin_addr : Unsigned_32;
+      padding  : Unsigned_64;
+   end record;
+   pragma Convention(C, sockaddr_in);
+   
+   -- Here we also don't care about the elements, only total mass:
+   type Socket is
+      record
+         SA : sockaddr_in;
+         FD : Interfaces.C.int;
+      end record;
+   pragma Convention(C, Socket);
+   
+   -- Everything below -- imports from unix_udp.c:
+   
+   procedure Unix_UDP_IP_To_String
+     (IP                 : Unsigned_32;
+      Output_Buffer      : System.Address;
+      Output_Buffer_Size : Unsigned_32);
+   pragma Import(C, Unix_UDP_IP_To_String, "unix_udp_ip_to_string");
+   
+   function Unix_UDP_String_To_IP
+     (Input_Buffer : System.Address;
+      IP           : not null access Unsigned_32) return Interfaces.C.int;
+   pragma Import(C, Unix_UDP_String_To_IP, "unix_udp_string_to_ip");
+   
+   function Unix_UDP_Socket_Open
+     (Socket     : System.Address;
+      Local_IP   : Unsigned_32;
+      Local_Port : Unsigned_16) return Interfaces.C.int;
+   pragma Import(C, Unix_UDP_Socket_Open, "unix_udp_socket_open");
+   
+   procedure Unix_UDP_Socket_Close
+     (Socket     : System.Address);
+   pragma Import(C, Unix_UDP_Socket_Close, "unix_udp_socket_close");
+   
+   function Unix_UDP_Socket_Transmit
+     (Socket      : System.Address;
+      Remote_IP   : Unsigned_32;
+      Remote_Port : Unsigned_16;
+      Payload_Buf : System.Address;
+      Payload_Len : Unsigned_32) return Interfaces.C.int;
+   pragma Import(C, Unix_UDP_Socket_Transmit, "unix_udp_socket_transmit");
+   
+   function Unix_UDP_Socket_Receive
+     (Socket      : System.Address;
+      Origin_IP   : not null access Unsigned_32;
+      Origin_Port : not null access Unsigned_16;
+      Payload_Buf : System.Address;
+      Payload_Len : Unsigned_32) return Interfaces.C.int;
+   pragma Import(C, Unix_UDP_Socket_Receive, "unix_udp_socket_receive");
+   
+end UDP;
diff -uNr a/udp/libudp/udp.gpr b/udp/libudp/udp.gpr
--- a/udp/libudp/udp.gpr false
+++ b/udp/libudp/udp.gpr 8547b598d4310c0a25ed8feb79159195e97c8b4546f7e5099490e5fdfb83e4f2869eee9efc77a0fd24448308192059252f986fa2b14b7de67ff3686eb422554c
@@ -0,0 +1,74 @@
+------------------------------------------------------------------------------
+------------------------------------------------------------------------------
+-- This file is part of 'UDP', a datagram sockets library.                  --
+--                                                                          --
+-- (C) 2018 Stanislav Datskovskiy ( www.loper-os.org )                      --
+-- http://wot.deedbot.org/17215D118B7239507FAFED98B98228A001ABFFC7.html     --
+--                                                                          --
+-- You do not have, nor can you ever acquire the right to use, copy or      --
+-- distribute this software ; Should you use this software for any purpose, --
+-- or copy and distribute it to anyone or in any manner, you are breaking   --
+-- the laws of whatever soi-disant jurisdiction, and you promise to         --
+-- continue doing so for the indefinite future. In any case, please         --
+-- always : read and understand any software ; verify any PGP signatures    --
+-- that you use - for any purpose.                                          --
+--                                                                          --
+-- See also http://trilema.com/2015/a-new-software-licensing-paradigm .     --
+------------------------------------------------------------------------------
+------------------------------------------------------------------------------
+
+project UDP is
+  
+  for Object_Dir use "obj";
+  
+  type Mode_Type is ("debug", "release");
+  Mode : Mode_Type := external ("mode", "release");
+  
+  for Languages    use ("Ada", "C");
+  for Source_Dirs  use (".");
+  for Library_Dir  use "lib";
+  for Library_Name use "UDP";
+  for Library_Kind use "static";
+  
+  package Compiler is
+    for Leading_Required_Switches ("C") use ("-c");
+    for Object_File_Suffix ("C") use ".o";
+    for Include_Switches ("C") use ("-I");
+
+     case Mode is
+        when "debug" =>
+           for Switches ("Ada")
+             use ("-g");
+        when "release" =>
+           for Switches ("Ada")
+             use ("-O2", "-fdump-scos", "-gnata", "-fstack-check",
+                  "-gnatyd", "-gnatym",
+                  "-fdata-sections", "-ffunction-sections", "-gnatwr", "-gnatw.d",
+                  "-gnatec=" & UDP'Project_Dir & "restrict.adc");
+           for Switches ("C")
+             use ("-O2", "-Wall", "-fstack-check");
+     end case;
+  end Compiler;
+  
+  package Naming is
+     for Spec_Suffix ("C") use ".h";
+     for Body_Suffix ("C") use ".c";
+  end Naming;
+  
+  package Builder is
+     for Switches ("Ada")
+       use ("-nostdlib");
+  end Builder;
+  
+  package Binder is
+     case Mode is
+        when "debug" =>
+           for Switches ("Ada")
+             use ();
+        when "release" =>
+           for Switches ("Ada")
+             use ("-static");
+     end case;
+  end Binder;
+  
+end UDP;
diff -uNr a/udp/libudp/unix_udp.c b/udp/libudp/unix_udp.c
--- a/udp/libudp/unix_udp.c false
+++ b/udp/libudp/unix_udp.c 1ce3fce5802bd1c1df524a6c3e1c9b2a45c62535d72602be8c7ef81e47cc543ce4d150ae2f1dca99d7b77f64209d2f47789ae08dee79473009f0531df1b77aa0
@@ -0,0 +1,139 @@
+/*
+------------------------------------------------------------------------------
+------------------------------------------------------------------------------
+-- This file is part of 'UDP', a datagram sockets library.                  --
+--                                                                          --
+-- (C) 2018 Stanislav Datskovskiy ( www.loper-os.org )                      --
+-- http://wot.deedbot.org/17215D118B7239507FAFED98B98228A001ABFFC7.html     --
+--                                                                          --
+-- You do not have, nor can you ever acquire the right to use, copy or      --
+-- distribute this software ; Should you use this software for any purpose, --
+-- or copy and distribute it to anyone or in any manner, you are breaking   --
+-- the laws of whatever soi-disant jurisdiction, and you promise to         --
+-- continue doing so for the indefinite future. In any case, please         --
+-- always : read and understand any software ; verify any PGP signatures    --
+-- that you use - for any purpose.                                          --
+--                                                                          --
+-- See also http://trilema.com/2015/a-new-software-licensing-paradigm .     --
+------------------------------------------------------------------------------
+------------------------------------------------------------------------------
+*/
+
+#include <string.h>
+#include <unistd.h>
+#include <arpa/inet.h>
+#include <netinet/in.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+
+
+/* Socket state representation: */
+typedef struct _UDP_Socket {
+  struct sockaddr_in sa_local;
+  int sock;
+} UDP_Socket;
+
+
+/* local-endian ip to string conversion */
+void unix_udp_ip_to_string(uint32_t ip, char *buf, uint32_t buf_size) {
+  struct in_addr addr;
+  addr.s_addr = htonl(ip);
+  char *txt = inet_ntoa(addr);
+  strncpy(buf, txt, buf_size);
+}
+
+
+/* string to local-endian ip conversion */
+int unix_udp_string_to_ip(char *buf, uint32_t *ip) {
+  struct in_addr addr;
+  if (inet_aton(buf, &addr) <= 0)
+    return -1;
+  *ip = ntohl(addr.s_addr);
+  return 0;
+}
+
+
+int unix_udp_socket_open(UDP_Socket *S,
+                         uint32_t local_ip, uint16_t local_port) {
+  /* Open the socket FD: */
+  if ((S->sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) {
+    return -1;
+  }
+  
+  memset(&S->sa_local, 0, sizeof(struct sockaddr_in));
+  
+  /* Set up emitter endpoint, converting from local endianness: */
+  S->sa_local.sin_family = AF_INET;
+  S->sa_local.sin_addr.s_addr = htonl(local_ip);
+  S->sa_local.sin_port = htons(local_port);
+  
+  /* Cure the asinine linuxism where dead sockets interfere with living: */
+  int one = 1;
+  if (setsockopt(S->sock, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one)) < 0) {
+    close(S->sock);
+    return -2;
+  }
+  
+  /* Bind the socket */
+  if (bind(S->sock,
+           (struct sockaddr *)&(S->sa_local), sizeof(S->sa_local)) < 0) {
+    close(S->sock);
+    return -3;
+  }
+  
+  /* ok */
+  return 0;
+}
+
+
+void unix_udp_socket_close(UDP_Socket *S) {
+  close(S->sock);
+}
+
+
+int unix_udp_socket_transmit(UDP_Socket *S,
+                             uint32_t remote_ip, uint16_t remote_port,
+                             uint8_t *payload, uint32_t payload_len) {
+  int bytes_sent = 0;
+  struct sockaddr_in remote_addr;
+  memset((char *)&remote_addr, 0, sizeof(remote_addr));
+  
+  /* Set up dest endpoint, converting from local endianness: */
+  remote_addr.sin_family = AF_INET;
+  remote_addr.sin_port = htons(remote_port);
+  remote_addr.sin_addr.s_addr = htonl(remote_ip);
+  
+  /* Transmit Datagram */
+  bytes_sent = sendto(S->sock, payload, payload_len,
+                      0, /* no flags */
+                      (struct sockaddr*)&remote_addr,
+                      sizeof(remote_addr));
+  if (bytes_sent <= 0)
+    return -1;
+  
+  return bytes_sent;
+}
+
+
+int unix_udp_socket_receive(UDP_Socket *S,
+                            uint32_t *origin_ip, uint16_t *origin_port,
+                            uint8_t *payload, uint32_t payload_len) {
+  int bytes_received = 0;
+  struct sockaddr_in orig_addr;
+  socklen_t orig_addr_len = sizeof(orig_addr);
+  memset((char *)&orig_addr, 0, sizeof(orig_addr));
+  
+  /* Receive Datagram (blocking!) */
+  bytes_received = recvfrom(S->sock, payload, payload_len,
+                            0, /* no flags */
+                            (struct sockaddr *)&orig_addr,
+                            &orig_addr_len);
+  
+  if (bytes_received < 0) return -1;
+
+  /* Save the originator's endpoint in ~local~ endianness */
+  *origin_ip = ntohl(orig_addr.sin_addr.s_addr);
+  *origin_port = ntohs(orig_addr.sin_port);
+  
+  return bytes_received;
+}
diff -uNr a/udp/manifest b/udp/manifest
--- a/udp/manifest false
+++ b/udp/manifest 5e6a00d7ade4d49943694a4158f8e30c101a0fd47116632d6ab4ec42358d506b0e4ebce8d199a5dfbd6b6684a3e2da67f50509e4ad19707f405cfe4e07599242
@@ -0,0 +1 @@
+543080 udp_genesis diana_coman Regrind of asciilifeform's UDP lib genesis, to bring it to current format (Keccak hashes, manifest file and standard compliant names for vpatches). A minimal library for UDP communications with fixed-size payloads sent/received over the wire. Uses Ada and C code.
diff -uNr a/udp/txdemo/bin/README b/udp/txdemo/bin/README
--- a/udp/txdemo/bin/README false
+++ b/udp/txdemo/bin/README 5fdbae897eb301a711bf95707f329517db540e34c182a5beec96e93d5d0d856cec2ed6b01c1191f865e8d1c45709a462c70c3005d4aa3676eb445d1479edf2e5
@@ -0,0 +1 @@
+Placeholder.
diff -uNr a/udp/txdemo/obj/README b/udp/txdemo/obj/README
--- a/udp/txdemo/obj/README false
+++ b/udp/txdemo/obj/README 5fdbae897eb301a711bf95707f329517db540e34c182a5beec96e93d5d0d856cec2ed6b01c1191f865e8d1c45709a462c70c3005d4aa3676eb445d1479edf2e5
@@ -0,0 +1 @@
+Placeholder.
diff -uNr a/udp/txdemo/udp_tx_demo.adb b/udp/txdemo/udp_tx_demo.adb
--- a/udp/txdemo/udp_tx_demo.adb false
+++ b/udp/txdemo/udp_tx_demo.adb 40398049eb151a9d306259d68a3865847c6591020ad12da0d9e374df9b5b8b7c2812576ed9298e83b115ac6636fe402b398c0810287e0cbf7904a05d2632f918
@@ -0,0 +1,93 @@
+------------------------------------------------------------------------------
+------------------------------------------------------------------------------
+-- This file is part of 'UDP Tx Demo', accompanies 'UDP' library.           --
+--                                                                          --
+-- (C) 2018 Stanislav Datskovskiy ( www.loper-os.org )                      --
+-- http://wot.deedbot.org/17215D118B7239507FAFED98B98228A001ABFFC7.html     --
+--                                                                          --
+-- You do not have, nor can you ever acquire the right to use, copy or      --
+-- distribute this software ; Should you use this software for any purpose, --
+-- or copy and distribute it to anyone or in any manner, you are breaking   --
+-- the laws of whatever soi-disant jurisdiction, and you promise to         --
+-- continue doing so for the indefinite future. In any case, please         --
+-- always : read and understand any software ; verify any PGP signatures    --
+-- that you use - for any purpose.                                          --
+--                                                                          --
+-- See also http://trilema.com/2015/a-new-software-licensing-paradigm .     --
+------------------------------------------------------------------------------
+------------------------------------------------------------------------------
+
+with Ada.Text_IO; use Ada.Text_IO;
+with Interfaces; use Interfaces;
+
+with UDP; use UDP;
+
+
+procedure UDP_Tx_Demo is
+   
+   Socket           : UDP.Socket;
+   
+   
+   Local_Endpoint   : UDP.Endpoint := (Address => UDP.INADDR_ANY,
+                                       Port    => 5000);
+   
+   Remote_Endpoint   : UDP.Endpoint
+     := (Address => UDP.IP_From_String("0.0.0.0"),
+         Port    => 7000);
+   
+   ----- Dulap test, replace with your own  -----
+   --  Remote_Endpoint   : UDP.Endpoint
+   --    := (Address => UDP.IP_From_String("161.0.121.200"),
+   --        Port    => 7000);
+   ----------------------------------------------
+   
+   Sent_Payload     : UDP.Payload;
+   Received_Payload : UDP.Payload;
+   Received_Origin  : UDP.Endpoint;
+   Received_Valid   : Boolean;
+   
+begin
+   Put_Line("Generating " &
+              UDP.Payload_Size'Image(Sent_Payload'Length) & "-byte turd...");
+   
+   for I in Sent_Payload'Range loop
+      Sent_Payload(I) := Unsigned_8(I mod 256);
+   end loop;
+   
+   Put_Line("Opening socket on local endpoint " &
+              UDP.IP_To_String(Local_Endpoint.Address) &
+              " :" & UDP.IP_Port'Image(Local_Endpoint.Port) & "...");
+   
+   UDP.Open_Socket(Socket, Local_Endpoint);
+   
+   Put_Line("Sending turd to " &
+              UDP.IP_To_String(Remote_Endpoint.Address) &
+              " :" & UDP.IP_Port'Image(Remote_Endpoint.Port) & "...");
+   
+   UDP.Transmit(Socket, Remote_Endpoint, Sent_Payload);
+   
+   Put_Line("Waiting for echo...");
+   
+   UDP.Receive(Socket, Received_Origin, Received_Payload, Received_Valid);
+   
+   Put_Line("Received payload from " &
+              UDP.IP_To_String(Received_Origin.Address) &
+              " :" & UDP.IP_Port'Image(Received_Origin.Port) & "...");
+   
+   if Received_Valid then
+      
+      if Received_Payload = Sent_Payload then
+         Put_Line("Echo came back equal to the send turd!");
+      else
+         Put_Line("Echo came back mutilated!");
+      end if;
+      
+   else
+      
+      Put_Line("Received short payload, ignored.");
+      
+   end if;
+   
+   Put_Line("Done.");
+
+end UDP_Tx_Demo;
diff -uNr a/udp/txdemo/udp_tx_demo.gpr b/udp/txdemo/udp_tx_demo.gpr
--- a/udp/txdemo/udp_tx_demo.gpr false
+++ b/udp/txdemo/udp_tx_demo.gpr f9c36b2555141df7bc0f8be870c0f60c8d8d35f93ba165f8b489d2ccbacd789b750bbd35b8eaa30664df7447a704eddfc8771de2c74e1f2c3a3472c7b9894669
@@ -0,0 +1,69 @@
+------------------------------------------------------------------------------
+------------------------------------------------------------------------------
+-- This file is part of 'UDP Tx Demo', accompanies 'UDP' library.           --
+--                                                                          --
+-- (C) 2018 Stanislav Datskovskiy ( www.loper-os.org )                      --
+-- http://wot.deedbot.org/17215D118B7239507FAFED98B98228A001ABFFC7.html     --
+--                                                                          --
+-- You do not have, nor can you ever acquire the right to use, copy or      --
+-- distribute this software ; Should you use this software for any purpose, --
+-- or copy and distribute it to anyone or in any manner, you are breaking   --
+-- the laws of whatever soi-disant jurisdiction, and you promise to         --
+-- continue doing so for the indefinite future. In any case, please         --
+-- always : read and understand any software ; verify any PGP signatures    --
+-- that you use - for any purpose.                                          --
+--                                                                          --
+-- See also http://trilema.com/2015/a-new-software-licensing-paradigm .     --
+------------------------------------------------------------------------------
+------------------------------------------------------------------------------
+
+with "../libudp/udp.gpr";
+
+project UDP_Tx_Demo is
+  
+  for Object_Dir use "obj";
+  
+  type Mode_Type is ("debug", "release");
+  Mode : Mode_Type := external ("mode", "release");
+  
+  for Languages   use ("Ada");
+  for Source_Dirs use (".");
+  for Exec_Dir    use "bin";
+  for Main        use ("udp_tx_demo.adb");
+  
+  package Compiler is
+     case Mode is
+        when "debug" =>
+           for Switches ("Ada")
+             use ("-g");
+        when "release" =>
+           for Switches ("Ada")
+             use ("-O2", "-fdump-scos", "-gnata", "-fstack-check",
+                  "-gnatyd", "-gnatym",
+                  "-fdata-sections", "-ffunction-sections");
+     end case;
+  end Compiler;
+  
+  package Binder is
+     case Mode is
+        when "debug" =>
+           for Switches ("Ada")
+             use ();
+        when "release" =>
+           for Switches ("Ada")
+             use ("-static");
+     end case;
+  end Binder;
+
+  package Linker is
+     case Mode is
+        when "debug" =>
+           for Switches ("Ada")
+             use ();
+        when "release" =>
+           for Switches ("Ada")
+             use ("-Wl,--gc-sections", "-static");
+     end case;
+  end Linker;
+  
+end UDP_Tx_Demo;