1

In Ada how can I best iterate over adapters (to find the assigned IP and subnet) in a OS independent manner? Is there a package like Gnat Sockets that I can use? Below is the code we currently use - however this is uses the Windows API directly. How can I best achieve the same thing without being Windows specific?

function Get_Adapters_Info (The_Adapter_Info     : Ip_Adapter_Info_Access;
                          Output_Buffer_Length : Win32.PULONG) return Win32.DWORD;
pragma Import (Stdcall, Get_Adapters_Info, "GetAdaptersInfo");


procedure Iterate_Ip_Addresses (Handler : not null access procedure (The_Information : Ip_Address_Info)) is
    Return_Code : Win32.DWORD;
    The_Size    : aliased Win32.ULONG := 0;
    use type Win32.DWORD;
    use type Win32.UINT;
begin
    Return_Code := Get_Adapters_Info (null, The_Size'unchecked_access); --'
    if The_Size > 0 then
        declare
        function Convert is new Ada.Unchecked_Conversion (System.Address, Ip_Adapter_Info_Access);
        The_Buffer : Unsigned.Byte_String (1..Natural(The_Size));
        The_Info   : Ip_Adapter_Info_Access := Convert (The_Buffer(The_Buffer'first)'address);
        begin
          Return_Code := Get_Adapters_Info (The_Info, The_Size'unchecked_access); --'
          if Return_Code = Win32.Winerror.NO_ERROR then
              loop
                  if (The_Info.Kind = Mib_If_Type_Ethernet) or (The_Info.Kind = Mib_If_Type_Ieee80211) then
                      declare
                          Ip_Address_List : Ip_Addr_String_Access := The_Info.Ip_Address_List'unchecked_access; --'
                      begin
                          loop
                              declare
                                  The_Address : constant Ip_Address :=  Convert(Ip_Address_List.Ip_Address);
                                  use type Ip_Address;

                              begin
                                  if The_Address /= Any_Address then -- Active
                                      Handler.all (The_Information => (The_Address => The_Address,
                                                   Subnet_Mask     => Convert(Ip_Address_List.Ip_Mask)));
                                  end if;
                              end;
                              Ip_Address_List := Ip_Address_List.Next;
                              exit when Ip_Address_List = null;
                          end loop;
                      end;
                  end if;
                  The_Info := The_Info.Next;
                  exit when The_Info = null;
              end loop;
          end if;
        end;
    end if;
end Iterate_Ip_Addresses;
Shark8
  • 4,095
  • 1
  • 17
  • 31
AhlanM
  • 21
  • 2
  • Unless there's some existing library for Ada that handles it for you, then there is no portable or OS-independent way of doing this. – Some programmer dude May 25 '15 at 08:19
  • I would start by looking at the Gnat.Sockets package. http://en.wikibooks.org/wiki/Ada_Programming/Libraries/GNAT.Sockets I don't think it provides such a low level interface to networking hardware, but it must use something of the sort internally. Alternatively, if you can find such a library in another language, probably C, you can easily generate bindings to it. –  May 25 '15 at 13:21
  • Side note: I just looked up `GetAdaptersInfo` to see what it was, and the Microsoft page I found said to use `GetAdaptersAddresses` on XP and later. XP is dead, so `GetAdaptersInfo` must be _really_ out of date. https://msdn.microsoft.com/en-us/library/windows/desktop/aa365917%28v=vs.85%29.aspx – ajb May 26 '15 at 04:17

1 Answers1

2

The Ada standard does not cover network programming, so the short, unsatisfying answer is no.

As these operations are operating system dependent, the best suggestion I can offer is to hide the operating system dependence:

  • Move your specification of Get_Adapters_Info into the body of Iterate_IP_Addresses.
  • Make the body of Iterate_IP_Addresses separate.
  • Supply an implementation (body) of Iterate_IP_Addresses for each operating system you want to support.
  • Select the appropriate implementation of Iterate_IP_Addresses at compile-time as a part of your build procedure.
Jacob Sparre Andersen
  • 6,733
  • 17
  • 22