From owner-svn-ports-all@FreeBSD.ORG Tue Feb 25 14:57:11 2014 Return-Path: Delivered-To: svn-ports-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) (using TLSv1 with cipher ADH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id AF6C56E9; Tue, 25 Feb 2014 14:57:11 +0000 (UTC) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mx1.freebsd.org (Postfix) with ESMTPS id 9A236122B; Tue, 25 Feb 2014 14:57:11 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.8/8.14.8) with ESMTP id s1PEvBti059204; Tue, 25 Feb 2014 14:57:11 GMT (envelope-from marino@svn.freebsd.org) Received: (from marino@localhost) by svn.freebsd.org (8.14.8/8.14.8/Submit) id s1PEv8f9059179; Tue, 25 Feb 2014 14:57:08 GMT (envelope-from marino@svn.freebsd.org) Message-Id: <201402251457.s1PEv8f9059179@svn.freebsd.org> From: John Marino Date: Tue, 25 Feb 2014 14:57:07 +0000 (UTC) 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 X-SVN-Group: ports-head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-ports-all@freebsd.org X-Mailman-Version: 2.1.17 Precedence: list List-Id: SVN commit messages for the ports tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 25 Feb 2014 14:57:11 -0000 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 +# $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 + +.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 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