aboutsummaryrefslogtreecommitdiffstats
path: root/net/anet/files
diff options
context:
space:
mode:
authormarino <marino@FreeBSD.org>2014-02-25 22:57:07 +0800
committermarino <marino@FreeBSD.org>2014-02-25 22:57:07 +0800
commit451583a79f1b6381bfa1f97d74764ff862a022ff (patch)
tree1be7e398c238d02be787b3aea4bd8028e9fd2cca /net/anet/files
parent45270f6f2f24cca27af6863231e18a02a9f81f88 (diff)
downloadfreebsd-ports-gnome-451583a79f1b6381bfa1f97d74764ff862a022ff.tar.gz
freebsd-ports-gnome-451583a79f1b6381bfa1f97d74764ff862a022ff.tar.zst
freebsd-ports-gnome-451583a79f1b6381bfa1f97d74764ff862a022ff.zip
Add new port net/anet (Ada IPv4 and IPv6 sockets binding library)
The ANet library was created on Linux and the unfortunate result is that it is highly Linux-specific. Luckily it has an implementation testsuite, so patches to make it work on BSD can be reasonably tested. The current status is annoted in pkg-message: ========================================================================= Beware of the IPv6 multicast functions. Sending does work, but the default interface effectively is invalid on *BSD. A specific interface needs to be provided rather than leaving interface blank (zero). Multicast receiving may not currently work. The test for IPv6 multicast fails. The test chunk is sent (verified with separate monitoring tool) but never detected. Hopefully the cause will be understood and fixed soon. AF_NETLINK and AF_PACKET protocols are not supported by *BSD, so the associated tests have been removed. Every test other than IPv6 Multicast passes. You may want to replace "em0" with this system's interface in the test suite is to be run (see files/patch-tests_socket__tests.adb).
Diffstat (limited to 'net/anet/files')
-rw-r--r--net/anet/files/patch-Makefile11
-rw-r--r--net/anet/files/patch-src_anet-constants.ads28
-rw-r--r--net/anet/files/patch-src_anet-sockets-inet.adb263
-rw-r--r--net/anet/files/patch-src_anet-sockets-inet.ads15
-rw-r--r--net/anet/files/patch-src_anet-sockets-netlink.adb12
-rw-r--r--net/anet/files/patch-src_anet-sockets-packet.adb12
-rw-r--r--net/anet/files/patch-src_anet-sockets-thin.ads156
-rw-r--r--net/anet/files/patch-src_anet-sockets-unix.adb30
-rw-r--r--net/anet/files/patch-src_anet-sockets.adb71
-rw-r--r--net/anet/files/patch-src_anet-sockets.ads28
-rw-r--r--net/anet/files/patch-tests_net__ifaces__tests.adb28
-rw-r--r--net/anet/files/patch-tests_socket__tests.adb38
12 files changed, 692 insertions, 0 deletions
diff --git a/net/anet/files/patch-Makefile b/net/anet/files/patch-Makefile
new file mode 100644
index 000000000000..c7fcfad0786a
--- /dev/null
+++ b/net/anet/files/patch-Makefile
@@ -0,0 +1,11 @@
+--- Makefile.orig 2013-12-04 09:55:07.000000000 +0000
++++ Makefile
+@@ -22,7 +22,7 @@ INSTALL_PROGRAM = $(INSTALL)
+ INSTALL_DATA = $(INSTALL) --mode=644 --preserve-timestamps
+ INSTALL_ALI = $(INSTALL) --mode=444
+
+-NUM_CPUS := $(shell getconf _NPROCESSORS_ONLN)
++NUM_CPUS ?= 1
+
+ # GNAT_BUILDER_FLAGS, ADAFLAGS and GNATFLAGS may be overridden in the
+ # environment or on the command line.
diff --git a/net/anet/files/patch-src_anet-constants.ads b/net/anet/files/patch-src_anet-constants.ads
new file mode 100644
index 000000000000..14772b64ed7e
--- /dev/null
+++ b/net/anet/files/patch-src_anet-constants.ads
@@ -0,0 +1,28 @@
+--- src/anet-constants.ads.orig 2013-12-04 09:55:07.000000000 +0000
++++ src/anet-constants.ads
+@@ -70,17 +70,19 @@ package Anet.Constants is
+
+ SO_BINDTODEVICE : constant := 25; -- Bind to interface device
+ SO_ATTACH_FILTER : constant := 26; -- Socket filtering
+- IPV6_ADD_MEMBERSHIP : constant := 20; -- Join multicast group (IPv6)
++ IPV6_ADD_MEMBERSHIP : constant := 12; -- Join multicast group (IPv6)
++ IPV6_MULTICAST_IF : constant := 9; -- Multicast sending (IPv6)
++ IP_MULTICAST_IF : constant := 9; -- Multicast sending on IF
+
+ -----------------------------------
+ -- Socket configuration controls --
+ -----------------------------------
+
+- SIOCGIFADDR : constant := 16#8915#; -- Get address
+- SIOCGIFFLAGS : constant := 16#8913#; -- Get flags
+- SIOCSIFFLAGS : constant := 16#8914#; -- Set flags
+- SIOCGIFHWADDR : constant := 16#8927#; -- Get hardware address
+- SIOCGIFINDEX : constant := 16#8933#; -- Name -> if_index mapping
++ SIOCGIFADDR : constant := 16#C0206921#; -- Get address
++ SIOCGIFFLAGS : constant := 16#C0206911#; -- Get flags
++ SIOCSIFFLAGS : constant := 16#80206910#; -- Set flags
++ SIOCGIFHWADDR : constant := 16#FFFFFFFF#; -- Get hardware address
++ SIOCGIFINDEX : constant := 16#C0206920#; -- Name -> if_index mapping
+
+ ---------------------
+ -- Interface flags --
diff --git a/net/anet/files/patch-src_anet-sockets-inet.adb b/net/anet/files/patch-src_anet-sockets-inet.adb
new file mode 100644
index 000000000000..7c39d9e73e03
--- /dev/null
+++ b/net/anet/files/patch-src_anet-sockets-inet.adb
@@ -0,0 +1,263 @@
+--- src/anet-sockets-inet.adb.orig 2013-12-04 09:55:07.000000000 +0000
++++ src/anet-sockets-inet.adb
+@@ -25,6 +25,7 @@ with Anet.Constants;
+ with Anet.Sockets.Thin;
+ with Anet.Byte_Swapping;
+ with Anet.Net_Ifaces;
++with Interfaces.C.Strings;
+
+ package body Anet.Sockets.Inet is
+
+@@ -61,7 +62,7 @@ package body Anet.Sockets.Inet is
+ is
+ Res : C.int;
+ Sock : Thin.Sockaddr_In_Type (Family => Family_Inet);
+- Len : aliased C.int := Sock'Size / 8;
++ Len : aliased C.int := 16;
+ begin
+ New_Socket.Sock_FD := -1;
+
+@@ -88,7 +89,7 @@ package body Anet.Sockets.Inet is
+ is
+ Res : C.int;
+ Sock : Thin.Sockaddr_In_Type (Family => Family_Inet6);
+- Len : aliased C.int := Sock'Size / 8;
++ Len : aliased C.int := 28;
+ begin
+ New_Socket.Sock_FD := -1;
+
+@@ -126,17 +127,16 @@ package body Anet.Sockets.Inet is
+
+ Res := Thin.C_Bind (S => Socket.Sock_FD,
+ Name => Sockaddr'Address,
+- Namelen => Sockaddr'Size / 8);
++ Namelen => 16);
+ if Res = C_Failure then
+ raise Socket_Error with "Unable to bind IPv4 socket to "
+ & To_String (Address => Address) & "," & Port'Img & " - "
+ & Get_Errno_String;
+ end if;
+
++ -- No BSD supports SO_BINDTODEVICE unfortunately....
+ if Iface'Length /= 0 then
+- Socket.Set_Socket_Option
+- (Option => Bind_To_Device,
+- Value => String (Iface));
++ Socket.Set_Multicast_Interface (IPAddr => Address);
+ end if;
+ end Bind;
+
+@@ -148,29 +148,35 @@ package body Anet.Sockets.Inet is
+ Port : Port_Type;
+ Iface : Types.Iface_Name_Type := "")
+ is
+- Res : C.int;
+- Sockaddr : constant Thin.Sockaddr_In_Type
+- := Create_Inet6 (Address => Address,
+- Port => Port);
++ Res : C.int;
++ Sockaddr : Thin.Sockaddr_In_Type;
++ Iface_Idx : Natural;
++ IfAddr6 : IPv6_Addr_Type;
+ begin
+ Socket.Set_Socket_Option
+ (Option => Reuse_Address,
+ Value => True);
+
++ if Iface'Length > 0 then
++ Get_IPv6_Interface_Data
++ (Iface_Name => Iface,
++ Iface_Index => Iface_Idx,
++ IPv6_Address => IfAddr6);
++ Socket.Set_Multicast_Interface (Idx => Iface_Idx);
++ Sockaddr := Create_Inet6 (Address => IfAddr6, Port => 0);
++ else
++ Sockaddr := Create_Inet6 (Address => Address, Port => Port);
++ end if;
++
+ Res := Thin.C_Bind (S => Socket.Sock_FD,
+ Name => Sockaddr'Address,
+- Namelen => Sockaddr'Size / 8);
++ Namelen => 28);
+ if Res = C_Failure then
+ raise Socket_Error with "Unable to bind IPv6 socket to "
+ & To_String (Address => Address) & "," & Port'Img & " - "
+ & Get_Errno_String;
+ end if;
+
+- if Iface'Length /= 0 then
+- Socket.Set_Socket_Option
+- (Option => Bind_To_Device,
+- Value => String (Iface));
+- end if;
+ end Bind;
+
+ -------------------------------------------------------------------------
+@@ -187,7 +193,7 @@ package body Anet.Sockets.Inet is
+ begin
+ Res := Thin.C_Connect (S => Socket.Sock_FD,
+ Name => Dst'Address,
+- Namelen => Dst'Size / 8);
++ Namelen => 16);
+
+ if Res = C_Failure then
+ raise Socket_Error with "Unable to connect socket to address "
+@@ -210,7 +216,7 @@ package body Anet.Sockets.Inet is
+ begin
+ Res := Thin.C_Connect (S => Socket.Sock_FD,
+ Name => Dst'Address,
+- Namelen => Dst'Size / 8);
++ Namelen => 28);
+
+ if Res = C_Failure then
+ raise Socket_Error with "Unable to connect socket to address "
+@@ -228,6 +234,7 @@ package body Anet.Sockets.Inet is
+ is
+ begin
+ return (Family => Family_Inet,
++ Sin_Len => 16,
+ Sin_Family => Constants.Sys.AF_INET,
+ Sin_Port => C.unsigned_short
+ (Byte_Swapping.Host_To_Network (Input => Port)),
+@@ -244,6 +251,7 @@ package body Anet.Sockets.Inet is
+ is
+ begin
+ return (Family => Family_Inet6,
++ Sin_Len => 28,
+ Sin_Family => Constants.Sys.AF_INET6,
+ Sin_Port => C.unsigned_short
+ (Byte_Swapping.Host_To_Network (Input => Port)),
+@@ -253,6 +261,51 @@ package body Anet.Sockets.Inet is
+
+ -------------------------------------------------------------------------
+
++ procedure Get_IPv6_Interface_Data
++ (Iface_Name : Types.Iface_Name_Type;
++ Iface_Index : out Natural;
++ IPv6_Address : out IPv6_Addr_Type)
++ is
++ use Interfaces.C;
++ use Anet.Sockets.Thin;
++ Res : C.int;
++
++ ifaddrs : aliased Thin.Ifaddrs_Type_Access;
++ frame : Thin.Ifaddrs_Type_Access;
++ found : Boolean := False;
++ begin
++ Res := Thin.C_GetIfAddrs (ptr_ifaddrs => ifaddrs'Access);
++ if Res = C_Failure then
++ raise Socket_Error with "Unable to get interface addresses: "
++ & Get_Errno_String;
++ end if;
++ frame := ifaddrs;
++ Iface_Index := 1;
++ loop
++ declare
++ testname : constant String :=
++ Interfaces.C.Strings.Value (frame.all.ifa_name);
++ begin
++ if testname = String (Iface_Name) and then
++ frame.all.ifa_addr.all.Sin_Family = Constants.Sys.AF_INET6 then
++ found := True;
++ IPv6_Address := frame.all.ifa_addr.all.Sin6_Addr;
++ end if;
++ end;
++ exit when found;
++ exit when frame.all.ifa_next = null;
++ frame := frame.all.ifa_next;
++ Iface_Index := Iface_Index + 1;
++ end loop;
++ Thin.C_FreeIfAddrs (ptr_ifaddrs => ifaddrs);
++ if not found then
++ raise Socket_Error with "Cannot find interface "
++ & String (Iface_Name);
++ end if;
++ end Get_IPv6_Interface_Data;
++
++ -------------------------------------------------------------------------
++
+ procedure Init (Socket : in out UDPv4_Socket_Type)
+ is
+ begin
+@@ -301,15 +354,15 @@ package body Anet.Sockets.Inet is
+ use type C.unsigned_short;
+
+ Mreq : Thin.IPv4_Mreq_Type;
+- Iface_Idx : Natural := 0;
++ ImrIface : IPv4_Addr_Type := (0, 0, 0, 0); -- INADDR_ANY
+ Res : C.int;
+ begin
+ if Iface'Length > 0 then
+- Iface_Idx := Net_Ifaces.Get_Iface_Index (Name => Iface);
++ ImrIface := Net_Ifaces.Get_Iface_IP (Name => Iface);
+ end if;
+
+ Mreq.Imr_Multiaddr := Group;
+- Mreq.Imr_Interface := C.unsigned (Iface_Idx);
++ Mreq.Imr_Interface := ImrIface;
+
+ Res := Thin.C_Setsockopt
+ (S => Socket.Sock_FD,
+@@ -335,10 +388,14 @@ package body Anet.Sockets.Inet is
+
+ Mreq6 : Thin.IPv6_Mreq_Type;
+ Iface_Idx : Natural := 0;
++ dummy : IPv6_Addr_Type;
+ Res : C.int;
+ begin
+ if Iface'Length > 0 then
+- Iface_Idx := Net_Ifaces.Get_Iface_Index (Name => Iface);
++ Get_IPv6_Interface_Data
++ (Iface_Name => Iface,
++ Iface_Index => Iface_Idx,
++ IPv6_Address => dummy);
+ end if;
+
+ Mreq6.IPv6mr_Multiaddr := Group;
+@@ -349,7 +406,7 @@ package body Anet.Sockets.Inet is
+ Level => Constants.IPPROTO_IPV6,
+ Optname => Constants.IPV6_ADD_MEMBERSHIP,
+ Optval => Mreq6'Address,
+- Optlen => Mreq6'Size / 8);
++ Optlen => 20);
+
+ if Res = C_Failure then
+ raise Socket_Error with "Unable to join multicast group "
+@@ -440,7 +497,8 @@ package body Anet.Sockets.Inet is
+ Dst_Addr : IPv4_Addr_Type;
+ Dst_Port : Port_Type)
+ is
+- Res : C.int;
++ use Interfaces.C;
++ Res : C.long;
+ Dst : constant Thin.Sockaddr_In_Type := Create_Inet4
+ (Address => Dst_Addr,
+ Port => Dst_Port);
+@@ -450,7 +508,7 @@ package body Anet.Sockets.Inet is
+ Len => Item'Length,
+ Flags => 0,
+ To => Dst'Address,
+- Tolen => Dst'Size / 8);
++ Tolen => 16);
+
+ if Res = C_Failure then
+ raise Socket_Error with "Error sending data to "
+@@ -473,7 +531,8 @@ package body Anet.Sockets.Inet is
+ Dst_Addr : IPv6_Addr_Type;
+ Dst_Port : Port_Type)
+ is
+- Res : C.int;
++ use Interfaces.C;
++ Res : C.long;
+ Dst : constant Thin.Sockaddr_In_Type := Create_Inet6
+ (Address => Dst_Addr,
+ Port => Dst_Port);
+@@ -483,7 +542,7 @@ package body Anet.Sockets.Inet is
+ Len => Item'Length,
+ Flags => 0,
+ To => Dst'Address,
+- Tolen => Dst'Size / 8);
++ Tolen => 28);
+
+ if Res = C_Failure then
+ raise Socket_Error with "Error sending data to "
diff --git a/net/anet/files/patch-src_anet-sockets-inet.ads b/net/anet/files/patch-src_anet-sockets-inet.ads
new file mode 100644
index 000000000000..91303d859e53
--- /dev/null
+++ b/net/anet/files/patch-src_anet-sockets-inet.ads
@@ -0,0 +1,15 @@
+--- src/anet-sockets-inet.ads.orig 2013-12-04 09:55:07.000000000 +0000
++++ src/anet-sockets-inet.ads
+@@ -174,6 +174,12 @@ package Anet.Sockets.Inet is
+ Port : Port_Type);
+ -- Connect TCPv6 socket to specified IPv6 address and port.
+
++ procedure Get_IPv6_Interface_Data
++ (Iface_Name : Types.Iface_Name_Type;
++ Iface_Index : out Natural;
++ IPv6_Address : out IPv6_Addr_Type);
++ -- Get IPv6 address and index from an interface name
++
+ private
+
+ type Inet_Socket_Type is abstract new Socket_Type with null record;
diff --git a/net/anet/files/patch-src_anet-sockets-netlink.adb b/net/anet/files/patch-src_anet-sockets-netlink.adb
new file mode 100644
index 000000000000..2ccbdebb01f6
--- /dev/null
+++ b/net/anet/files/patch-src_anet-sockets-netlink.adb
@@ -0,0 +1,12 @@
+--- src/anet-sockets-netlink.adb.orig 2013-12-04 09:55:07.000000000 +0000
++++ src/anet-sockets-netlink.adb
+@@ -128,7 +128,8 @@ package body Anet.Sockets.Netlink is
+ Item : Ada.Streams.Stream_Element_Array;
+ To : Netlink_Addr_Type)
+ is
+- Res : C.int;
++ use Interfaces.C;
++ Res : C.long;
+ Dst : Thin.Sockaddr_Nl_Type
+ := (Nl_Pid => Interfaces.Unsigned_32 (To),
+ others => <>);
diff --git a/net/anet/files/patch-src_anet-sockets-packet.adb b/net/anet/files/patch-src_anet-sockets-packet.adb
new file mode 100644
index 000000000000..2a7287020ec5
--- /dev/null
+++ b/net/anet/files/patch-src_anet-sockets-packet.adb
@@ -0,0 +1,12 @@
+--- src/anet-sockets-packet.adb.orig 2013-12-04 09:55:07.000000000 +0000
++++ src/anet-sockets-packet.adb
+@@ -129,7 +129,8 @@ package body Anet.Sockets.Packet is
+ To : Hardware_Addr_Type;
+ Iface : Types.Iface_Name_Type)
+ is
+- Res : C.int;
++ use Interfaces.C;
++ Res : C.long;
+ Ll_Dest : Thin.Sockaddr_Ll_Type;
+ begin
+ Ll_Dest.Sa_Ifindex := C.int (Net_Ifaces.Get_Iface_Index
diff --git a/net/anet/files/patch-src_anet-sockets-thin.ads b/net/anet/files/patch-src_anet-sockets-thin.ads
new file mode 100644
index 000000000000..5c52ad90df54
--- /dev/null
+++ b/net/anet/files/patch-src_anet-sockets-thin.ads
@@ -0,0 +1,156 @@
+--- src/anet-sockets-thin.ads.orig 2013-12-04 09:55:07.000000000 +0000
++++ src/anet-sockets-thin.ads
+@@ -22,11 +22,14 @@
+ --
+
+ with System;
++with Interfaces.C.Strings;
+
+ package Anet.Sockets.Thin is
+
+ type Sockaddr_Type is record
+- Sa_Family : Interfaces.C.unsigned_short;
++ Sa_Len : Interfaces.C.unsigned_char := 16;
++ -- Record Size (BSD)
++ Sa_Family : Interfaces.C.unsigned_char;
+ -- Address family
+ Sa_Data : Interfaces.C.char_array (1 .. 14)
+ := (others => Interfaces.C.nul);
+@@ -39,7 +42,9 @@ package Anet.Sockets.Thin is
+ -- Internet protocol address families.
+
+ type Sockaddr_In_Type (Family : Family_Inet_Type := Family_Inet) is record
+- Sin_Family : Interfaces.C.unsigned_short;
++ Sin_Len : Interfaces.C.unsigned_char;
++ -- Record length (BSD)
++ Sin_Family : Interfaces.C.unsigned_char;
+ -- Address family
+ Sin_Port : Interfaces.C.unsigned_short;
+ -- Port in network byte order
+@@ -64,10 +69,14 @@ package Anet.Sockets.Thin is
+ -- Low-level Internet socket address type (struct sockaddr_in, struct
+ -- sockaddr_in6).
+
++ type Sockaddr_In_Type_Access is access all Sockaddr_In_Type;
++
+ type Sockaddr_Un_Type is record
+- Sin_Family : Interfaces.C.unsigned_short := Constants.AF_UNIX;
++ Sun_Len : Interfaces.C.unsigned_char;
++ -- Record Length (BSD)
++ Sun_Family : Interfaces.C.unsigned_char := Constants.AF_UNIX;
+ -- Address family
+- Pathname : Interfaces.C.char_array (1 .. Constants.UNIX_PATH_MAX)
++ Pathname : Interfaces.C.char_array (1 .. 104)
+ := (others => Interfaces.C.nul);
+ -- Pathname
+ end record;
+@@ -108,7 +117,7 @@ package Anet.Sockets.Thin is
+
+ type IPv4_Mreq_Type is record
+ Imr_Multiaddr : IPv4_Addr_Type;
+- Imr_Interface : Interfaces.C.unsigned;
++ Imr_Interface : IPv4_Addr_Type;
+ end record;
+ pragma Convention (C, IPv4_Mreq_Type);
+ -- struct ip_mreq (netinet/in.h).
+@@ -120,6 +129,21 @@ package Anet.Sockets.Thin is
+ pragma Convention (C, IPv6_Mreq_Type);
+ -- struct ipv6_mreq (netinet/in.h).
+
++ type Ifaddrs_Type;
++ type Ifaddrs_Type_Access is access all Ifaddrs_Type;
++
++ type Ifaddrs_Type is record
++ ifa_next : Ifaddrs_Type_Access;
++ ifa_name : Interfaces.C.Strings.chars_ptr;
++ ifa_flags : Interfaces.C.unsigned;
++ ifa_addr : Sockaddr_In_Type_Access;
++ ifa_netmask : Sockaddr_In_Type_Access;
++ ifa_dstaddr : Sockaddr_In_Type_Access;
++ ifa_data : System.Address;
++ end record;
++ pragma Convention (C, Ifaddrs_Type);
++ -- struct ipv6_mreq (ifaddrs.h).
++
+ type Netdev_Request_Name is
+ (If_Addr,
+ If_Flags,
+@@ -146,16 +170,18 @@ package Anet.Sockets.Thin is
+ pragma Convention (C, If_Req_Type);
+ -- Interface request structure (struct ifreq).
+
+- Get_Requests : constant array (Netdev_Request_Name) of Interfaces.C.int
++ Get_Requests : constant array (Netdev_Request_Name) of
++ Interfaces.C.unsigned_long
+ := (If_Addr => Constants.SIOCGIFADDR,
+ If_Flags => Constants.SIOCGIFFLAGS,
+ If_Hwaddr => Constants.SIOCGIFHWADDR,
+ If_Index => Constants.SIOCGIFINDEX);
+ -- Currently supported netdevice ioctl get requests.
+
+- Set_Requests : constant array (Netdev_Request_Name) of Interfaces.C.int
++ Set_Requests : constant array (Netdev_Request_Name) of
++ Interfaces.C.unsigned_long
+ := (If_Flags => Constants.SIOCSIFFLAGS,
+- others => Interfaces.C.int (-1));
++ others => Interfaces.C.unsigned_long (16#FFFFFFFF#));
+ -- Currently supported netdevice ioctl set requests.
+
+ -------------
+@@ -179,7 +205,7 @@ package Anet.Sockets.Thin is
+ function C_Connect
+ (S : Interfaces.C.int;
+ Name : System.Address;
+- Namelen : Interfaces.C.int)
++ Namelen : Interfaces.C.unsigned)
+ return Interfaces.C.int;
+ pragma Import (C, C_Connect, "connect");
+
+@@ -204,19 +230,19 @@ package Anet.Sockets.Thin is
+ function C_Send
+ (S : Interfaces.C.int;
+ Buf : System.Address;
+- Len : Interfaces.C.int;
++ Len : Interfaces.C.unsigned;
+ Flags : Interfaces.C.int)
+- return Interfaces.C.int;
++ return Interfaces.C.long;
+ pragma Import (C, C_Send, "send");
+
+ function C_Sendto
+ (S : Interfaces.C.int;
+ Buf : System.Address;
+- Len : Interfaces.C.int;
++ Len : Interfaces.C.unsigned;
+ Flags : Interfaces.C.int;
+ To : System.Address;
+- Tolen : Interfaces.C.int)
+- return Interfaces.C.int;
++ Tolen : Interfaces.C.unsigned)
++ return Interfaces.C.long;
+ pragma Import (C, C_Sendto, "sendto");
+
+ function C_Setsockopt
+@@ -243,7 +269,7 @@ package Anet.Sockets.Thin is
+
+ function C_Ioctl
+ (S : Interfaces.C.int;
+- Req : Interfaces.C.int;
++ Req : Interfaces.C.unsigned_long;
+ Arg : access If_Req_Type)
+ return Interfaces.C.int;
+ pragma Import (C, C_Ioctl, "ioctl");
+@@ -251,4 +277,13 @@ package Anet.Sockets.Thin is
+ function C_Close (Fd : Interfaces.C.int) return Interfaces.C.int;
+ pragma Import (C, C_Close, "close");
+
++ function C_GetIfAddrs
++ (ptr_ifaddrs : not null access Ifaddrs_Type_Access)
++ return Interfaces.C.int;
++ pragma Import (C, C_GetIfAddrs, "getifaddrs");
++
++ procedure C_FreeIfAddrs
++ (ptr_ifaddrs : not null Ifaddrs_Type_Access);
++ pragma Import (C, C_FreeIfAddrs, "freeifaddrs");
++
+ end Anet.Sockets.Thin;
diff --git a/net/anet/files/patch-src_anet-sockets-unix.adb b/net/anet/files/patch-src_anet-sockets-unix.adb
new file mode 100644
index 000000000000..f3a34b37c2fc
--- /dev/null
+++ b/net/anet/files/patch-src_anet-sockets-unix.adb
@@ -0,0 +1,30 @@
+--- src/anet-sockets-unix.adb.orig 2013-12-04 09:55:07.000000000 +0000
++++ src/anet-sockets-unix.adb
+@@ -68,6 +68,7 @@ package body Anet.Sockets.Unix is
+ begin
+ OS.Delete_File (Filename => String (Path));
+
++ Value.Sun_Len := C_Path'Length;
+ Value.Pathname (1 .. C_Path'Length) := C_Path;
+
+ Res := Thin.C_Bind (S => Socket.Sock_FD,
+@@ -101,15 +102,18 @@ package body Anet.Sockets.Unix is
+ (Socket : in out Unix_Socket_Type;
+ Path : Path_Type)
+ is
++ use Interfaces.C;
+ Res : C.int;
+ C_Path : constant C.char_array := C.To_C (String (Path));
+ Value : Thin.Sockaddr_Un_Type;
++ ValLen : C.unsigned;
+ begin
+ Value.Pathname (1 .. C_Path'Length) := C_Path;
++ ValLen := Value'Size / 8;
+
+ Res := Thin.C_Connect (S => Socket.Sock_FD,
+ Name => Value'Address,
+- Namelen => Value'Size / 8);
++ Namelen => ValLen);
+
+ if Res = C_Failure then
+ raise Socket_Error with "Unable to connect unix socket to path "
diff --git a/net/anet/files/patch-src_anet-sockets.adb b/net/anet/files/patch-src_anet-sockets.adb
new file mode 100644
index 000000000000..9ae248bfbf47
--- /dev/null
+++ b/net/anet/files/patch-src_anet-sockets.adb
@@ -0,0 +1,71 @@
+--- src/anet-sockets.adb.orig 2013-12-04 09:55:07.000000000 +0000
++++ src/anet-sockets.adb
+@@ -54,7 +54,7 @@ package body Anet.Sockets is
+
+ procedure Check_Complete_Send
+ (Item : Ada.Streams.Stream_Element_Array;
+- Result : Interfaces.C.int;
++ Result : Interfaces.C.long;
+ Error_Msg : String)
+ is
+ use Ada.Streams;
+@@ -197,7 +197,8 @@ package body Anet.Sockets is
+ (Socket : Socket_Type;
+ Item : Ada.Streams.Stream_Element_Array)
+ is
+- Res : C.int;
++ use Interfaces.C;
++ Res : C.long;
+ begin
+ Res := Thin.C_Send (S => Socket.Sock_FD,
+ Buf => Item'Address,
+@@ -217,6 +218,49 @@ package body Anet.Sockets is
+
+ -------------------------------------------------------------------------
+
++ procedure Set_Multicast_Interface
++ (Socket : Socket_Type;
++ IPAddr : IPv4_Addr_Type)
++ is
++ Res : C.int;
++ begin
++ Res := Thin.C_Setsockopt
++ (S => Socket.Sock_FD,
++ Level => Constants.Sys.IPPROTO_IP,
++ Optname => Constants.Sys.IP_MULTICAST_IF,
++ Optval => IPAddr'Address,
++ Optlen => 4);
++
++ if Res = C_Failure then
++ raise Socket_Error with "Unable set IPv4 Multicast IF option "
++ & " on '" & To_String (IPAddr) & "': " & Get_Errno_String;
++ end if;
++ end Set_Multicast_Interface;
++
++ -------------------------------------------------------------------------
++
++ procedure Set_Multicast_Interface
++ (Socket : Socket_Type;
++ Idx : Natural)
++ is
++ Res : C.int;
++ IF_Index : constant C.unsigned := C.unsigned (Idx);
++ begin
++ Res := Thin.C_Setsockopt
++ (S => Socket.Sock_FD,
++ Level => Constants.IPPROTO_IPV6,
++ Optname => Constants.IPV6_MULTICAST_IF,
++ Optval => IF_Index'Address,
++ Optlen => 4);
++
++ if Res = C_Failure then
++ raise Socket_Error with "Unable set IPv6 Multicast IF option"
++ & " on interface'" & Idx'Img & "': " & Get_Errno_String;
++ end if;
++ end Set_Multicast_Interface;
++
++ -------------------------------------------------------------------------
++
+ procedure Set_Socket_Option
+ (Socket : Socket_Type;
+ Option : Option_Name_Bool;
diff --git a/net/anet/files/patch-src_anet-sockets.ads b/net/anet/files/patch-src_anet-sockets.ads
new file mode 100644
index 000000000000..e041ae1b546e
--- /dev/null
+++ b/net/anet/files/patch-src_anet-sockets.ads
@@ -0,0 +1,28 @@
+--- src/anet-sockets.ads.orig 2013-12-04 09:55:07.000000000 +0000
++++ src/anet-sockets.ads
+@@ -120,6 +120,16 @@ package Anet.Sockets is
+ Value : String);
+ -- Set socket option of given socket to specified string value.
+
++ procedure Set_Multicast_Interface
++ (Socket : Socket_Type;
++ IPAddr : IPv4_Addr_type);
++ -- Set multicast interface socket option for IPv4
++
++ procedure Set_Multicast_Interface
++ (Socket : Socket_Type;
++ Idx : Natural);
++ -- Set multicast interface socket option for IPv6
++
+ Socket_Error : exception;
+
+ private
+@@ -171,7 +181,7 @@ private
+
+ procedure Check_Complete_Send
+ (Item : Ada.Streams.Stream_Element_Array;
+- Result : Interfaces.C.int;
++ Result : Interfaces.C.long;
+ Error_Msg : String);
+ -- Verify that a Send operation was able to transmit all bytes of given
+ -- buffer by calculating the actual number of bytes sent from the buffer
diff --git a/net/anet/files/patch-tests_net__ifaces__tests.adb b/net/anet/files/patch-tests_net__ifaces__tests.adb
new file mode 100644
index 000000000000..b6e4e1766edf
--- /dev/null
+++ b/net/anet/files/patch-tests_net__ifaces__tests.adb
@@ -0,0 +1,28 @@
+--- tests/net_ifaces_tests.adb.orig 2013-12-04 09:55:07.000000000 +0000
++++ tests/net_ifaces_tests.adb
+@@ -45,8 +45,9 @@ package body Net_Ifaces_Tests is
+ when Sockets.Socket_Error => null;
+ end;
+
+- Assert (Condition => Net_Ifaces.Get_Iface_Index (Name => "lo") = 1,
+- Message => "Loopback index not 1");
++ -- Loopback interface is not expected to be first on BSD, bad assertion
++ -- Assert (Condition => Net_Ifaces.Get_Iface_Index (Name => "lo") = 1,
++ -- Message => "Loopback index not 1");
+ end Get_Loopback_Interface_Index;
+
+ -------------------------------------------------------------------------
+@@ -89,9 +90,10 @@ package body Net_Ifaces_Tests is
+ T.Add_Test_Routine
+ (Routine => Get_Loopback_Interface_Index'Access,
+ Name => "Get iface index for loopback");
+- T.Add_Test_Routine
+- (Routine => Get_Loopback_Interface_Mac'Access,
+- Name => "Get iface hw addr for loopback");
++ -- hw addr is not supported on BSD
++ -- T.Add_Test_Routine
++ -- (Routine => Get_Loopback_Interface_Mac'Access,
++ -- Name => "Get iface hw addr for loopback");
+ T.Add_Test_Routine
+ (Routine => Get_Loopback_Interface_IP'Access,
+ Name => "Get iface IP addr for loopback");
diff --git a/net/anet/files/patch-tests_socket__tests.adb b/net/anet/files/patch-tests_socket__tests.adb
new file mode 100644
index 000000000000..33d0650856cd
--- /dev/null
+++ b/net/anet/files/patch-tests_socket__tests.adb
@@ -0,0 +1,38 @@
+--- tests/socket_tests.adb.orig 2013-12-04 09:55:07.000000000 +0000
++++ tests/socket_tests.adb
+@@ -203,15 +203,15 @@ package body Socket_Tests is
+ T.Add_Test_Routine
+ (Routine => Send_Unix_Datagram'Access,
+ Name => "Send data (Unix, datagram)");
+- T.Add_Test_Routine
+- (Routine => Send_Netlink_Raw'Access,
+- Name => "Send data (Netlink, raw)");
+- T.Add_Test_Routine
+- (Routine => Send_Packet_Datagram'Access,
+- Name => "Send data (Packet, datagram)");
+- T.Add_Test_Routine
+- (Routine => Send_Packet_Raw'Access,
+- Name => "Send data (Packet, raw)");
++ -- T.Add_Test_Routine
++ -- (Routine => Send_Netlink_Raw'Access,
++ -- Name => "Send data (Netlink, raw)");
++ -- T.Add_Test_Routine
++ -- (Routine => Send_Packet_Datagram'Access,
++ -- Name => "Send data (Packet, datagram)");
++ -- T.Add_Test_Routine
++ -- (Routine => Send_Packet_Raw'Access,
++ -- Name => "Send data (Packet, raw)");
+ T.Add_Test_Routine
+ (Routine => Send_Various_Buffers'Access,
+ Name => "Send data (various buffer ranges)");
+@@ -333,8 +333,9 @@ package body Socket_Tests is
+ begin
+ Sock.Init;
+ Sock.Bind (Address => Grp,
++ Iface => "em0",
+ Port => Test_Utils.Listen_Port);
+- Sock.Join_Multicast_Group (Group => Grp);
++ Sock.Join_Multicast_Group (Group => Grp, Iface => "em0");
+
+ Rcvr.Listen (Callback => Test_Utils.Dump'Access);
+