1-- 2-- Copyright (C) 2011-2013 secunet Security Networks AG 3-- Copyright (C) 2011-2014 Reto Buerki <reet@codelabs.ch> 4-- Copyright (C) 2011-2014 Adrian-Ken Rueegsegger <ken@codelabs.ch> 5-- 6-- This program is free software; you can redistribute it and/or modify it 7-- under the terms of the GNU General Public License as published by the 8-- Free Software Foundation; either version 2 of the License, or (at your 9-- option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>. 10-- 11-- This program is distributed in the hope that it will be useful, but 12-- WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 13-- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14-- for more details. 15-- 16-- As a special exception, if other files instantiate generics from this 17-- unit, or you link this unit with other files to produce an 18-- executable this unit does not by itself cause the resulting 19-- executable to be covered by the GNU General Public License. This 20-- exception does not however invalidate any other reasons why the 21-- executable file might be covered by the GNU Public License. 22-- 23 24private with Ada.Finalization; 25 26with Interfaces.C; 27 28with Anet.Constants; 29with Anet.Socket_Families; 30 31package Anet.Sockets is 32 33 type Mode_Type is 34 (Datagram_Socket, 35 Raw_Socket, 36 Stream_Socket); 37 -- Supported socket modes. 38 39 type Level_Type is (Socket_Level, TCP_Level); 40 -- Protocol level type. 41 42 type Sock_Shutdown_Cmd is 43 (Block_Reception, 44 Block_Transmission, 45 Block_All_Communication); 46 -- Socket shutdown methods. 47 48 type Socket_Type is abstract tagged limited private; 49 -- Communication socket. 50 51 procedure Close (Socket : in out Socket_Type); 52 -- Close given socket. 53 54 procedure Shutdown 55 (Socket : Socket_Type; 56 Method : Sock_Shutdown_Cmd); 57 -- Controlled shutdown of given socket. 58 59 procedure Send 60 (Socket : Socket_Type; 61 Item : Ada.Streams.Stream_Element_Array); 62 -- Send data on socket to connected endpoint. 63 64 procedure Receive 65 (Socket : Socket_Type; 66 Item : out Ada.Streams.Stream_Element_Array; 67 Last : out Ada.Streams.Stream_Element_Offset); 68 -- Receive data from given socket. This procedure blocks until data has 69 -- been received. Last is the index value such that Item (Last) is the last 70 -- character assigned. An exception is raised if a socket error occurs. 71 72 procedure Listen 73 (Socket : Socket_Type; 74 Backlog : Positive := 1); 75 -- Listen for specified amount of requests on given socket. 76 77 -- Enable/disable non-blocking mode of operation. Newly created sockets 78 -- operate in blocking mode by default. 79 procedure Set_Nonblocking_Mode 80 (Socket : Socket_Type; 81 Enable : Boolean := True); 82 83 type Dgram_Socket_Type is limited interface; 84 -- Datagram socket. 85 86 type Stream_Socket_Type is limited interface; 87 -- Stream socket. 88 89 procedure Send 90 (Socket : Stream_Socket_Type; 91 Item : Ada.Streams.Stream_Element_Array) is abstract; 92 -- Send data on socket to connected endpoint. 93 94 procedure Receive 95 (Socket : Stream_Socket_Type; 96 Item : out Ada.Streams.Stream_Element_Array; 97 Last : out Ada.Streams.Stream_Element_Offset) is abstract; 98 -- Receive data from given socket. This procedure blocks until data has 99 -- been received. Last is the index value such that Item (Last) is the last 100 -- character assigned. An exception is raised if a socket error occurs. 101 102 procedure Listen 103 (Socket : Stream_Socket_Type; 104 Backlog : Positive := 1) is abstract; 105 -- Listen for specified amount of requests on given socket. 106 107 procedure Accept_Connection 108 (Socket : Stream_Socket_Type; 109 New_Socket : out Stream_Socket_Type) is abstract; 110 -- Accept first connection request from listening socket and return new 111 -- connected socket. 112 113 type Option_Name_Bool is 114 (Broadcast, 115 Reuse_Address, 116 TCP_Nodelay); 117 -- Supported boolean socket options. 118 119 type Option_Name_Str is (Bind_To_Device); 120 -- Supported string based socket options. 121 122 procedure Set_Socket_Option 123 (Socket : Socket_Type; 124 Level : Level_Type := Socket_Level; 125 Option : Option_Name_Bool; 126 Value : Boolean); 127 -- Set socket option of given socket to specified boolean value. The level 128 -- argument specifies the protocol level this option applies to. 129 130 procedure Set_Socket_Option 131 (Socket : Socket_Type; 132 Level : Level_Type := Socket_Level; 133 Option : Option_Name_Str; 134 Value : String); 135 -- Set socket option of given socket to specified string value. The level 136 -- argument specifies the protocol level this option applies to. 137 138private 139 140 use type Interfaces.C.int; 141 142 Modes : constant array (Mode_Type) of Interfaces.C.int 143 := (Datagram_Socket => Constants.Sys.SOCK_DGRAM, 144 Raw_Socket => Constants.SOCK_RAW, 145 Stream_Socket => Constants.Sys.SOCK_STREAM); 146 -- Socket mode mapping. 147 148 Levels : constant array (Level_Type) of Interfaces.C.int 149 := (Socket_Level => Constants.Sys.SOL_SOCKET, 150 TCP_Level => Constants.Sys.IPPROTO_TCP); 151 -- Protocol level mapping. 152 153 Options_Bool : constant array (Option_Name_Bool) of Interfaces.C.int 154 := (Reuse_Address => Constants.Sys.SO_REUSEADDR, 155 Broadcast => Constants.Sys.SO_BROADCAST, 156 TCP_Nodelay => Constants.Sys.TCP_NODELAY); 157 -- Mapping for option names with boolean value. 158 159 Options_Str : constant array (Option_Name_Str) of Interfaces.C.int 160 := (Bind_To_Device => Constants.SO_BINDTODEVICE); 161 -- Mapping for option names with string value. 162 163 Shutdown_Methods : constant array (Sock_Shutdown_Cmd) of Interfaces.C.int 164 := (Block_Reception => Constants.Sys.SHUT_RD, 165 Block_Transmission => Constants.Sys.SHUT_WR, 166 Block_All_Communication => Constants.Sys.SHUT_RDWR); 167 -- Mapping of socket shutdown methods. 168 169 type Socket_Type is new Ada.Finalization.Limited_Controlled with record 170 Sock_FD : Interfaces.C.int := -1; 171 Protocol : Double_Byte := 0; 172 end record; 173 174 overriding 175 procedure Finalize (Socket : in out Socket_Type); 176 -- Close socket. 177 178 procedure Init 179 (Socket : in out Socket_Type; 180 Family : Socket_Families.Family_Type; 181 Mode : Mode_Type; 182 Protocol : Double_Byte := 0); 183 -- Initialize given socket with specified family, mode and protocol. 184 185 procedure Check_Complete_Send 186 (Item : Ada.Streams.Stream_Element_Array; 187 Result : Interfaces.C.long; 188 Error_Msg : String); 189 -- Verify that a Send operation was able to transmit all bytes of given 190 -- buffer by calculating the actual number of bytes sent from the buffer 191 -- range and the send(2)/sendto(2) result specified. The procedure raises 192 -- an exception starting with the given error message if the check fails. 193 194 type Recv_Result_Type is 195 (Recv_Op_Ok, 196 Recv_Op_Aborted, 197 Recv_Op_Error, 198 Recv_Op_Orderly_Shutdown); 199 -- Receive operation result status. 200 201 function Check_Receive (Result : Interfaces.C.long) return Recv_Result_Type; 202 -- Determine the result of a receive operation. 203 204 type Accept_Result_Type is 205 (Accept_Op_Ok, 206 Accept_Op_Aborted, 207 Accept_Op_Error); 208 -- Accept operation result status. 209 210 function Check_Accept (Result : Interfaces.C.int) return Accept_Result_Type; 211 -- Determine the result of an accept operation. 212 213end Anet.Sockets; 214