net/anet: Upgrade version 0.2.3 => 0.3.0

This version fixes all the stuff the removed patches addressed (this
version was released as a direct result of these patches which I provided
upstream).  Multicast sending remains tricky, in part due to a known and
yet to be addressed bug in FreeBSD.

The pkg-message was deleted.  I don't completely understand what needs
to be established in order for IPv6 multicast to work (e.g. don't use
the same machine for sending and receiving) so rather than mislead, I
just removed this information for now.
This commit is contained in:
John Marino 2014-05-14 07:09:46 +00:00
parent d953e53990
commit c00060a304
Notes: svn2git 2021-03-31 03:12:20 +00:00
svn path=/head/; revision=354028
16 changed files with 18 additions and 726 deletions

View file

@ -2,8 +2,7 @@
# $FreeBSD$
PORTNAME= anet
PORTVERSION= 0.2.3
PORTREVISION= 2
PORTVERSION= 0.3.0
CATEGORIES= net
MASTER_SITES= http://www.codelabs.ch/download/
DISTNAME= libanet-${PORTVERSION}
@ -14,11 +13,11 @@ COMMENT= Networking library for Ada
LICENSE= GPLv2 GMGPL
LICENSE_COMB= multi
USES= ada
USE_BZIP2= yes
USES= ada tar:bzip2
ALL_TARGET= build_lib
MAKE_ARGS+= NUM_CPUS=${MAKE_JOBS_NUMBER} \
LIBRARY_KIND=static
LIBRARY_KIND=static \
OS=bsd
OPTIONS_DEFINE= TEST DOCS
TEST_DESC= Run unit test suite before installation
@ -42,10 +41,6 @@ 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' \

View file

@ -1,2 +1,2 @@
SHA256 (libanet-0.2.3.tar.bz2) = 13fa12b35fc63e85dead0adb4f02b9d28deaab4e30b0ca4f2eeee1d4e55efd1a
SIZE (libanet-0.2.3.tar.bz2) = 46569
SHA256 (libanet-0.3.0.tar.bz2) = a183dc7c11bac77bd30e8f23cb4b3aec693ac512c837a6061fa4f8e7f3d49e92
SIZE (libanet-0.3.0.tar.bz2) = 48860

View file

@ -1,11 +0,0 @@
--- 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.

View file

@ -1,28 +0,0 @@
--- 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 --

View file

@ -1,264 +0,0 @@
--- 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,52 @@ 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 +355,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 +389,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 +407,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 +498,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 +509,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 +532,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 +543,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 "

View file

@ -1,15 +0,0 @@
--- 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;

View file

@ -1,12 +0,0 @@
--- 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 => <>);

View file

@ -1,12 +0,0 @@
--- 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

View file

@ -1,156 +0,0 @@
--- 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;

View file

@ -1,30 +0,0 @@
--- 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 "

View file

@ -1,71 +0,0 @@
--- 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;

View file

@ -1,28 +0,0 @@
--- 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

View file

@ -1,28 +0,0 @@
--- 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");

View file

@ -1,38 +0,0 @@
--- 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);

View file

@ -1,14 +0,0 @@
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).

View file

@ -15,12 +15,10 @@ 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-iface.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-netdev.ads
include/anet/anet-sockets-thin.ads
include/anet/anet-sockets-unix.adb
include/anet/anet-sockets-unix.ads
@ -41,13 +39,19 @@ lib/anet/anet-constants.ali
lib/anet/anet-ipv4.ali
lib/anet/anet-net_ifaces.ali
lib/anet/anet-os.ali
lib/anet/anet-os_constants.ali
lib/anet/anet-receivers-datagram.ali
lib/anet/anet-receivers-stream.ali
lib/anet/anet-receivers.ali
lib/anet/anet-socket_families.ali
lib/anet/anet-sockets-filters.ali
lib/anet/anet-sockets-inet-iface.ali
lib/anet/anet-sockets-inet.ali
lib/anet/anet-sockets-netlink.ali
lib/anet/anet-sockets-packet.ali
lib/anet/anet-sockets-thin-inet.ali
lib/anet/anet-sockets-thin-netdev-requests.ali
lib/anet/anet-sockets-thin-netdev.ali
lib/anet/anet-sockets-thin-sockaddr.ali
lib/anet/anet-sockets-thin-unix.ali
lib/anet/anet-sockets-thin.ali
lib/anet/anet-sockets-unix.ali
lib/anet/anet-sockets.ali
@ -62,6 +66,6 @@ lib/gnat/anet.gpr
%%PORTDOCS%%%%DOCSDIR%%/html/index.html
%%PORTDOCS%%@dirrmtry %%DOCSDIR%%/html
%%PORTDOCS%%@dirrmtry %%DOCSDIR%%
@dirrmtry lib/gnat
@dirrm lib/anet
@dirrm include/anet
@dirrm lib/anet
@dirrmtry lib/gnat