Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 25 Feb 2014 14:57:07 +0000 (UTC)
From:      John Marino <marino@FreeBSD.org>
To:        ports-committers@freebsd.org, svn-ports-all@freebsd.org, svn-ports-head@freebsd.org
Subject:   svn commit: r346016 - in head/net: . anet anet/files
Message-ID:  <201402251457.s1PEv8f9059179@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: marino
Date: Tue Feb 25 14:57:07 2014
New Revision: 346016
URL: http://svnweb.freebsd.org/changeset/ports/346016
QAT: https://qat.redports.org/buildarchive/r346016/

Log:
  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).

Added:
  head/net/anet/
  head/net/anet/Makefile   (contents, props changed)
  head/net/anet/distinfo   (contents, props changed)
  head/net/anet/files/
  head/net/anet/files/patch-Makefile   (contents, props changed)
  head/net/anet/files/patch-src_anet-constants.ads   (contents, props changed)
  head/net/anet/files/patch-src_anet-sockets-inet.adb   (contents, props changed)
  head/net/anet/files/patch-src_anet-sockets-inet.ads   (contents, props changed)
  head/net/anet/files/patch-src_anet-sockets-netlink.adb   (contents, props changed)
  head/net/anet/files/patch-src_anet-sockets-packet.adb   (contents, props changed)
  head/net/anet/files/patch-src_anet-sockets-thin.ads   (contents, props changed)
  head/net/anet/files/patch-src_anet-sockets-unix.adb   (contents, props changed)
  head/net/anet/files/patch-src_anet-sockets.adb   (contents, props changed)
  head/net/anet/files/patch-src_anet-sockets.ads   (contents, props changed)
  head/net/anet/files/patch-tests_net__ifaces__tests.adb   (contents, props changed)
  head/net/anet/files/patch-tests_socket__tests.adb   (contents, props changed)
  head/net/anet/pkg-descr   (contents, props changed)
  head/net/anet/pkg-message   (contents, props changed)
  head/net/anet/pkg-plist   (contents, props changed)
Modified:
  head/net/Makefile

Modified: head/net/Makefile
==============================================================================
--- head/net/Makefile	Tue Feb 25 14:52:35 2014	(r346015)
+++ head/net/Makefile	Tue Feb 25 14:57:07 2014	(r346016)
@@ -17,6 +17,7 @@
     SUBDIR += adasockets
     SUBDIR += afpfs-ng
     SUBDIR += aget
+    SUBDIR += anet
     SUBDIR += aoe
     SUBDIR += apinger
     SUBDIR += appkonference

Added: head/net/anet/Makefile
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/net/anet/Makefile	Tue Feb 25 14:57:07 2014	(r346016)
@@ -0,0 +1,67 @@
+# Created by: John Marino <marino@FreeBSD.org>
+# $FreeBSD$
+
+PORTNAME=	anet
+PORTVERSION=	0.2.3
+CATEGORIES=	net
+MASTER_SITES=	http://www.codelabs.ch/download/
+DISTNAME=	libanet-${PORTVERSION}
+
+MAINTAINER=	marino@FreeBSD.org
+COMMENT=	Networking library for Ada
+
+LICENSE=	GPLv2 GMGPL
+LICENSE_COMB=	multi
+
+USES=		ada
+USE_BZIP2=	yes
+ALL_TARGET=	build_all
+MAKE_ARGS+=	NUM_CPUS=${MAKE_JOBS_NUMBER} \
+		LIBRARY_KIND=static
+
+OPTIONS_DEFINE=	TEST #DOCS
+TEST_DESC=	Run unit test suite before installation
+
+.include <bsd.port.options.mk>
+
+.if ${OPSYS} == DragonFly && ${ARCH} == i386
+IGNORE=		will not build; atomics are not supported on DF i386
+.endif
+
+.if ${PORT_OPTIONS:MTEST}
+BUILD_DEPENDS+=	${LOCALBASE}/lib/gnat/ahven.gpr:${PORTSDIR}/devel/ahven
+ALL_TARGET+=	tests
+.endif
+
+# DOCS disabled -- asciidoc generation missing source highlights
+#.if ${PORT_OPTIONS:MDOCS}
+#BUILD_DEPENDS+= asciidoc:${PORTSDIR}/textproc/asciidoc
+#ALL_TARGET+=	doc
+#USES+=		gmake
+#.endif
+
+post-patch:
+	@${REINPLACE_CMD} -e 's|"lo"|"lo0"|g' \
+		${WRKSRC}/tests/net_ifaces_tests.adb \
+		${WRKSRC}/tests/socket_tests.adb \
+		${WRKSRC}/tests/type_tests.adb
+	@${REINPLACE_CMD} -e 's|dynamic|static|g' \
+		${WRKSRC}/gnat/anet.gpr
+	@${REINPLACE_CMD} -e 's|DESTDIR|DEST2|g' \
+		${WRKSRC}/doc/Makefile
+
+do-build:
+	${MKDIR} ${WRKSRC}/doc/html
+	cd ${WRKSRC} && ${SETENV} ${MAKE_ENV} \
+		${MAKE_CMD} ${MAKE_ARGS} ${ALL_TARGET}
+
+do-install:
+	${MKDIR} ${STAGEDIR}${PREFIX}/lib/gnat \
+		${STAGEDIR}${PREFIX}/lib/anet \
+		${STAGEDIR}${PREFIX}/include/anet
+	${INSTALL_DATA} ${WRKSRC}/src/*.ad[bs] \
+		${STAGEDIR}${PREFIX}/include/anet
+	${INSTALL_DATA} ${WRKSRC}/lib/static/* ${STAGEDIR}${PREFIX}/lib/anet
+	${INSTALL_DATA} ${WRKSRC}/gnat/anet.gpr ${STAGEDIR}${PREFIX}/lib/gnat
+
+.include <bsd.port.mk>

Added: head/net/anet/distinfo
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/net/anet/distinfo	Tue Feb 25 14:57:07 2014	(r346016)
@@ -0,0 +1,2 @@
+SHA256 (libanet-0.2.3.tar.bz2) = 13fa12b35fc63e85dead0adb4f02b9d28deaab4e30b0ca4f2eeee1d4e55efd1a
+SIZE (libanet-0.2.3.tar.bz2) = 46569

Added: head/net/anet/files/patch-Makefile
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/net/anet/files/patch-Makefile	Tue Feb 25 14:57:07 2014	(r346016)
@@ -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.

Added: head/net/anet/files/patch-src_anet-constants.ads
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/net/anet/files/patch-src_anet-constants.ads	Tue Feb 25 14:57:07 2014	(r346016)
@@ -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 --

Added: head/net/anet/files/patch-src_anet-sockets-inet.adb
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/net/anet/files/patch-src_anet-sockets-inet.adb	Tue Feb 25 14:57:07 2014	(r346016)
@@ -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 "

Added: head/net/anet/files/patch-src_anet-sockets-inet.ads
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/net/anet/files/patch-src_anet-sockets-inet.ads	Tue Feb 25 14:57:07 2014	(r346016)
@@ -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;

Added: head/net/anet/files/patch-src_anet-sockets-netlink.adb
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/net/anet/files/patch-src_anet-sockets-netlink.adb	Tue Feb 25 14:57:07 2014	(r346016)
@@ -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 => <>);

Added: head/net/anet/files/patch-src_anet-sockets-packet.adb
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/net/anet/files/patch-src_anet-sockets-packet.adb	Tue Feb 25 14:57:07 2014	(r346016)
@@ -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

Added: head/net/anet/files/patch-src_anet-sockets-thin.ads
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/net/anet/files/patch-src_anet-sockets-thin.ads	Tue Feb 25 14:57:07 2014	(r346016)
@@ -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;

Added: head/net/anet/files/patch-src_anet-sockets-unix.adb
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/net/anet/files/patch-src_anet-sockets-unix.adb	Tue Feb 25 14:57:07 2014	(r346016)
@@ -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 "

Added: head/net/anet/files/patch-src_anet-sockets.adb
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/net/anet/files/patch-src_anet-sockets.adb	Tue Feb 25 14:57:07 2014	(r346016)
@@ -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;

Added: head/net/anet/files/patch-src_anet-sockets.ads
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/net/anet/files/patch-src_anet-sockets.ads	Tue Feb 25 14:57:07 2014	(r346016)
@@ -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

Added: head/net/anet/files/patch-tests_net__ifaces__tests.adb
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/net/anet/files/patch-tests_net__ifaces__tests.adb	Tue Feb 25 14:57:07 2014	(r346016)
@@ -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");

Added: head/net/anet/files/patch-tests_socket__tests.adb
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/net/anet/files/patch-tests_socket__tests.adb	Tue Feb 25 14:57:07 2014	(r346016)
@@ -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);
+ 

Added: head/net/anet/pkg-descr
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/net/anet/pkg-descr	Tue Feb 25 14:57:07 2014	(r346016)
@@ -0,0 +1,20 @@
+Anet is a networking library for the Ada programming language featuring:
+  * BSD socket implementation
+  * High abstraction level
+  * Extendable socket type hierarchy
+  * Socket receiver tasks (Stream and Datagram)
+  * Ada type serialisation/deserialisation over sockets
+  * Supported socket families
+    - IPv4 (AF_INET)
+    - IPv6 (AF_INET6)
+    - UNIX domain (AF_UNIX)
+    - Linux only: Packet (AF_PACKET)
+    - Linux only: Netlink (AF_NETLINK)
+  * Supported socket modes
+    - Stream (TCP)
+    - Datagram (UDP)
+    - RAW
+  * Support for IPv4/IPv6 multicast
+  * UDP/IPv4 packet creation and validation
+
+WWW: http://www.codelabs.ch/anet/

Added: head/net/anet/pkg-message
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/net/anet/pkg-message	Tue Feb 25 14:57:07 2014	(r346016)
@@ -0,0 +1,14 @@
+
+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).

Added: head/net/anet/pkg-plist
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/net/anet/pkg-plist	Tue Feb 25 14:57:07 2014	(r346016)
@@ -0,0 +1,63 @@
+include/anet/anet-byte_swapping.adb
+include/anet/anet-byte_swapping.ads
+include/anet/anet-constants.ads
+include/anet/anet-ipv4.adb
+include/anet/anet-ipv4.ads
+include/anet/anet-net_ifaces.adb
+include/anet/anet-net_ifaces.ads
+include/anet/anet-os.adb
+include/anet/anet-os.ads
+include/anet/anet-receivers-datagram.adb
+include/anet/anet-receivers-datagram.ads
+include/anet/anet-receivers-stream.adb
+include/anet/anet-receivers-stream.ads
+include/anet/anet-receivers.adb
+include/anet/anet-receivers.ads
+include/anet/anet-sockets-filters.adb
+include/anet/anet-sockets-filters.ads
+include/anet/anet-sockets-inet.adb
+include/anet/anet-sockets-inet.ads
+include/anet/anet-sockets-netlink.adb
+include/anet/anet-sockets-netlink.ads
+include/anet/anet-sockets-packet.adb
+include/anet/anet-sockets-packet.ads
+include/anet/anet-sockets-thin.ads
+include/anet/anet-sockets-unix.adb
+include/anet/anet-sockets-unix.ads
+include/anet/anet-sockets.adb
+include/anet/anet-sockets.ads
+include/anet/anet-streams.adb
+include/anet/anet-streams.ads
+include/anet/anet-types.adb
+include/anet/anet-types.ads
+include/anet/anet-udp.adb
+include/anet/anet-udp.ads
+include/anet/anet-util.adb
+include/anet/anet-util.ads
+include/anet/anet.adb
+include/anet/anet.ads
+lib/anet/anet-byte_swapping.ali
+lib/anet/anet-constants.ali
+lib/anet/anet-ipv4.ali
+lib/anet/anet-net_ifaces.ali
+lib/anet/anet-os.ali
+lib/anet/anet-receivers-datagram.ali
+lib/anet/anet-receivers-stream.ali
+lib/anet/anet-receivers.ali
+lib/anet/anet-sockets-filters.ali
+lib/anet/anet-sockets-inet.ali
+lib/anet/anet-sockets-netlink.ali
+lib/anet/anet-sockets-packet.ali
+lib/anet/anet-sockets-thin.ali
+lib/anet/anet-sockets-unix.ali
+lib/anet/anet-sockets.ali
+lib/anet/anet-streams.ali
+lib/anet/anet-types.ali
+lib/anet/anet-udp.ali
+lib/anet/anet-util.ali
+lib/anet/anet.ali
+lib/anet/libanet.a
+lib/gnat/anet.gpr
+@dirrmtry lib/gnat
+@dirrm lib/anet
+@dirrm include/anet



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201402251457.s1PEv8f9059179>