Skip to content

Commit

Permalink
Merge branch 'bmk/esock/20240605/getiflist_configure/OTP-19132' into …
Browse files Browse the repository at this point in the history
…maint
  • Loading branch information
bmk committed Jul 23, 2024
2 parents 5bbacce + 3a5d2ed commit 58cd1af
Show file tree
Hide file tree
Showing 8 changed files with 304 additions and 92 deletions.
3 changes: 3 additions & 0 deletions erts/config.h.in
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,9 @@
/* Socket address dl length */
#undef ESOCK_SDL_LEN

/* Interface hwaddr supported */
#undef ESOCK_USE_ENADDR

/* Use extended error info */
#undef ESOCK_USE_EXTENDED_ERROR_INFO

Expand Down
17 changes: 17 additions & 0 deletions erts/configure
Original file line number Diff line number Diff line change
Expand Up @@ -16659,6 +16659,23 @@ printf "%s\n" "#define ESOCK_USE_HWADDR /**/" >>confdefs.h
fi


ac_fn_c_check_member "$LINENO" "struct ifreq" "ifr_enaddr" "ac_cv_member_struct_ifreq_ifr_enaddr" "#ifdef __WIN32__
#else
#include <net/if.h>
#endif

"
if test "x$ac_cv_member_struct_ifreq_ifr_enaddr" = xyes
then :

printf "%s\n" "#define HAVE_STRUCT_IFREQ_IFR_ENADDR 1" >>confdefs.h


printf "%s\n" "#define ESOCK_USE_ENADDR /**/" >>confdefs.h

fi


ac_fn_c_check_member "$LINENO" "struct ifreq" "ifr_ifindex" "ac_cv_member_struct_ifreq_ifr_ifindex" "#ifdef __WIN32__
#else
#include <net/if.h>
Expand Down
9 changes: 9 additions & 0 deletions erts/configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -1446,6 +1446,15 @@ AC_CHECK_MEMBERS([struct ifreq.ifr_hwaddr],
#endif
])

AC_CHECK_MEMBERS([struct ifreq.ifr_enaddr],
[AC_DEFINE(ESOCK_USE_ENADDR, [], [Interface hwaddr supported])],
[],
[#ifdef __WIN32__
#else
#include <net/if.h>
#endif
])

AC_CHECK_MEMBERS([struct ifreq.ifr_ifindex],
[AC_DEFINE(ESOCK_USE_IFINDEX, [], [Interface ifindex supported])],
[],
Expand Down
3 changes: 3 additions & 0 deletions erts/emulator/nifs/common/prim_socket_nif.c
Original file line number Diff line number Diff line change
Expand Up @@ -2360,6 +2360,7 @@ ERL_NIF_TERM esock_atom_socket_tag; // This has a "special" name ('$socket')
LOCAL_ATOM_DECL(exclude); \
LOCAL_ATOM_DECL(false); \
LOCAL_ATOM_DECL(frag_needed); \
LOCAL_ATOM_DECL(genhwaddr); \
LOCAL_ATOM_DECL(gifaddr); \
LOCAL_ATOM_DECL(gifbrdaddr); \
LOCAL_ATOM_DECL(gifconf); \
Expand Down Expand Up @@ -4934,6 +4935,8 @@ ERL_NIF_TERM esock_supports_ioctl_requests(ErlNifEnv* env)

#if defined(SIOCGIFHWADDR) && defined(ESOCK_USE_HWADDR)
requests = MKC(env, MKT2(env, atom_gifhwaddr, MKUL(env, SIOCGIFHWADDR)), requests);
#elif defined(SIOCGENADDR) && defined(ESOCK_USE_ENADDR)
requests = MKC(env, MKT2(env, atom_genaddr, MKUL(env, SIOCGENADDR)), requests);
#endif

#if defined(SIOCGIFMAP) && defined(ESOCK_USE_IFMAP)
Expand Down
157 changes: 106 additions & 51 deletions erts/emulator/nifs/unix/unix_socket_syncio.c
Original file line number Diff line number Diff line change
Expand Up @@ -517,6 +517,13 @@ static ERL_NIF_TERM essio_ioctl_gifname(ErlNifEnv* env,
#define IOCTL_GIFHWADDR_FUNC3_DEF
#endif

/* esock_ioctl_gifenaddr */
#if defined(SIOCGENHWADDR) && defined(ESOCK_USE_ENADDR)
#define IOCTL_GIFENADDR_FUNC3_DEF IOCTL_GET_FUNC3_DEF(gifenaddr)
#else
#define IOCTL_GIFENADDR_FUNC3_DEF
#endif

/* esock_ioctl_gifmap */
#if defined(SIOCGIFMAP) && defined(ESOCK_USE_IFMAP)
#define IOCTL_GIFMAP_FUNC3_DEF IOCTL_GET_FUNC3_DEF(gifmap)
Expand All @@ -540,6 +547,7 @@ static ERL_NIF_TERM essio_ioctl_gifname(ErlNifEnv* env,
IOCTL_GIFNETMASK_FUNC3_DEF; \
IOCTL_GIFMTU_FUNC3_DEF; \
IOCTL_GIFHWADDR_FUNC3_DEF; \
IOCTL_GIFENADDR_FUNC3_DEF; \
IOCTL_GIFMAP_FUNC3_DEF; \
IOCTL_GIFTXQLEN_FUNC3_DEF;
#define IOCTL_GET_FUNC3_DEF(F) \
Expand Down Expand Up @@ -642,7 +650,8 @@ static ERL_NIF_TERM encode_ioctl_ifrmap(ErlNifEnv* env,
ESockDescriptor* descP,
struct ifmap* mapP);
#endif
#if defined(SIOCGIFHWADDR) && defined(ESOCK_USE_HWADDR)
#if (defined(SIOCGIFHWADDR) && defined(ESOCK_USE_HWADDR)) || \
(defined(SIOCGIFENADDR) && defined(ESOCK_USE_ENADDR))
static ERL_NIF_TERM encode_ioctl_hwaddr(ErlNifEnv* env,
ESockDescriptor* descP,
struct sockaddr* addrP);
Expand Down Expand Up @@ -4164,8 +4173,14 @@ ERL_NIF_TERM essio_ioctl3(ErlNifEnv* env,

#if defined(SIOCGIFHWADDR) && defined(ESOCK_USE_HWADDR)
case SIOCGIFHWADDR:
return essio_ioctl_gifhwaddr(env, descP, arg);
break;
return essio_ioctl_gifhwaddr(env, descP, arg);
break;
#endif

#if defined(SIOCGENHWADDR) && defined(ESOCK_USE_ENADDR)
case SIOCGIFENADDR:
return essio_ioctl_gifenaddr(env, descP, arg);
break;
#endif

#if defined(SIOCGIFMAP) && defined(ESOCK_USE_IFMAP)
Expand Down Expand Up @@ -4523,11 +4538,19 @@ IOCTL_GET_FUNCS2
/* *** essio_ioctl_gifhwaddr *** */
#if defined(SIOCGIFHWADDR) && defined(ESOCK_USE_HWADDR)
#define IOCTL_GIFHWADDR_FUNC3_DECL \
IOCTL_GET_REQUEST3_DECL(gifhwaddr, SIOCGIFHWADDR, hwaddr, &ifreq.ifr_hwaddr)
IOCTL_GET_REQUEST3_DECL(gifhwaddr, SIOCGIFHWADDR, hwaddr, &ifreq.ifr_hwaddr)
#else
#define IOCTL_GIFHWADDR_FUNC3_DECL
#endif

/* *** essio_ioctl_gifenaddr *** */
#if defined(SIOCGENADDR) && defined(ESOCK_USE_ENADDR)
#define IOCTL_GIFENADDR_FUNC3_DECL \
IOCTL_GET_REQUEST3_DECL(gifenaddr, SIOCGENENADDR, hwaddr, &ifreq.ifr_enaddr)
#else
#define IOCTL_GIFENADDR_FUNC3_DECL
#endif

/* *** essio_ioctl_gifmap *** */
#if defined(SIOCGIFMAP) && defined(ESOCK_USE_IFMAP)
#define IOCTL_GIFMAP_FUNC3_DECL \
Expand All @@ -4544,7 +4567,7 @@ IOCTL_GET_FUNCS2
#define IOCTL_GIFTXQLEN_FUNC3_DECL
#endif

#define IOCTL_GET_FUNCS3 \
#define IOCTL_GET_FUNCS3 \
IOCTL_GIFINDEX_FUNC3_DECL \
IOCTL_GIFFLAGS_FUNC3_DECL \
IOCTL_GIFADDR_FUNC3_DECL \
Expand All @@ -4553,6 +4576,7 @@ IOCTL_GET_FUNCS2
IOCTL_GIFNETMASK_FUNC3_DECL \
IOCTL_GIFMTU_FUNC3_DECL \
IOCTL_GIFHWADDR_FUNC3_DECL \
IOCTL_GIFENADDR_FUNC3_DECL \
IOCTL_GIFMAP_FUNC3_DECL \
IOCTL_GIFTXQLEN_FUNC3_DECL

Expand Down Expand Up @@ -4946,44 +4970,91 @@ ERL_NIF_TERM essio_ioctl_sifflags(ErlNifEnv* env,
*
*/

#if defined(AF_LINK) && !defined(NO_SA_LEN)
#define SIZEA(p) (((p).sa_len > sizeof(p)) ? (p).sa_len : sizeof(p))
#else
#define SIZEA(p) (sizeof (p))
#endif

static
ERL_NIF_TERM encode_ioctl_ifconf(ErlNifEnv* env,
ESockDescriptor* descP,
struct ifconf* ifcP)
{
ERL_NIF_TERM result;
unsigned int len = ((ifcP == NULL) ? 0 :
(ifcP->ifc_len / sizeof(struct ifreq)));
ERL_NIF_TERM result;
unsigned int len = (ifcP == NULL) ? 0 : ifcP->ifc_len;

SSDBG( descP,
("UNIX-ESSIO",
"encode_ioctl_ifconf -> entry (when len = %d)\r\n", len) );
SSDBG( descP,
("UNIX-ESSIO",
"encode_ioctl_ifconf -> entry with"
"\r\n (total) len: %d\r\n", len) );

if (len > 0) {
ERL_NIF_TERM* array = MALLOC(len * sizeof(ERL_NIF_TERM));
unsigned int i = 0;
struct ifreq* p = ifcP->ifc_req;
if (len > 0) {
ERL_NIF_TERM elem, array;
SocketTArray tarray = TARRAY_CREATE(32);
unsigned int n = 1; // Just for debugging
unsigned int i = 0;
unsigned int sz;
struct ifreq* ifrP;

for (i = 0 ; i < len ; i++) {
SSDBG( descP,
("UNIX-ESSIO",
"encode_ioctl_ifconf -> encode ifreq entry %d\r\n", i) );
array[i] = encode_ioctl_ifconf_ifreq(env, descP, &p[i]);
}
for (;;) {

SSDBG( descP,
("UNIX-ESSIO", "encode_ioctl_ifconf -> all entries encoded\r\n", i) );
SSDBG( descP,
("UNIX-ESSIO",
"encode_ioctl_ifconf -> encode entry %d at %d\r\n", n, i) );

result = esock_make_ok2(env, MKLA(env, array, len));
FREE(array);
ifrP = (struct ifreq*) VOIDP(ifcP->ifc_buf + i);
sz = sizeof(ifrP->ifr_name) + SIZEA(ifrP->ifr_addr);
if (sz < sizeof(*ifrP)) sz = sizeof(*ifrP);

} else {
SSDBG( descP,
("UNIX-ESSIO",
"encode_ioctl_ifconf -> "
"\r\n size: %d"
"\r\n Name len: %d"
"\r\n Addr len: %d"
"\r\n Rec len: %d"
"\r\n",
sz,
sizeof(ifrP->ifr_name),
SIZEA(ifrP->ifr_addr),
sizeof(*ifrP)) );

result = esock_make_ok2(env, MKEL(env));
i += sz;
if (i > len) break;

}
SSDBG( descP,
("UNIX-ESSIO",
"encode_ioctl_ifconf -> encode new entry\r\n") );

return result;
elem = encode_ioctl_ifconf_ifreq(env, descP, ifrP);

SSDBG( descP,
("UNIX-ESSIO",
"encode_ioctl_ifconf -> add new entry: "
"\r\n %T\r\n", elem) );

TARRAY_ADD(tarray, elem);

n++;
}

SSDBG( descP,
("UNIX-ESSIO",
"encode_ioctl_ifconf -> all entries encoded\r\n") );

TARRAY_TOLIST(tarray, env, &array);
result = esock_make_ok2(env, array);

} else {

result = esock_make_ok2(env, MKEL(env));

}

SSDBG( descP, ("UNIX-ESSIO", "encode_ioctl_ifconf -> done\r\n") );

return result;
}


Expand Down Expand Up @@ -5021,7 +5092,8 @@ ERL_NIF_TERM encode_ioctl_ifrmap(ErlNifEnv* env,
#endif


#if defined(SIOCGIFHWADDR) && defined(ESOCK_USE_HWADDR)
#if (defined(SIOCGIFHWADDR) && defined(ESOCK_USE_HWADDR)) || \
(defined(SIOCGIFENADDR) && defined(ESOCK_USE_ENADDR))
static
ERL_NIF_TERM encode_ioctl_hwaddr(ErlNifEnv* env,
ESockDescriptor* descP,
Expand Down Expand Up @@ -5127,6 +5199,7 @@ BOOLEAN_T decode_ioctl_sockaddr(ErlNifEnv* env,
}


#if defined(SIOCSIFHWADDR)
static
BOOLEAN_T decode_ioctl_hwaddr(ErlNifEnv* env,
ESockDescriptor* descP,
Expand All @@ -5147,30 +5220,11 @@ BOOLEAN_T decode_ioctl_hwaddr(ErlNifEnv* env,

return result;
}


/* #if defined(SIOCGIFHWADDR) && defined(ESOCK_USE_HWADDR) */
/* static */
/* ERL_NIF_TERM encode_ioctl_hwaddr(ErlNifEnv* env, */
/* ESockDescriptor* descP, */
/* struct sockaddr* addrP) */
/* { */
/* ERL_NIF_TERM eaddr; */
/* SOCKLEN_T sz = sizeof(struct sockaddr); */

/* esock_encode_hwsockaddr(env, addrP, sz, &eaddr); */

/* SSDBG( descP, ("UNIX-ESSIO", "encode_ioctl_hwaddr -> done with" */
/* "\r\n Sock Addr: %T" */
/* "\r\n", eaddr) ); */

/* return esock_make_ok2(env, eaddr);; */
/* } */
/* #endif */

#endif



#if defined(SIOCSIFMTU)
static
BOOLEAN_T decode_ioctl_mtu(ErlNifEnv* env,
ESockDescriptor* descP,
Expand All @@ -5191,6 +5245,7 @@ BOOLEAN_T decode_ioctl_mtu(ErlNifEnv* env,

return result;
}
#endif


#if defined(SIOCSIFTXQLEN)
Expand Down
23 changes: 22 additions & 1 deletion lib/kernel/src/inet.erl
Original file line number Diff line number Diff line change
Expand Up @@ -329,7 +329,10 @@ Function `parse_address/1` can be useful:
element(1, Record) =:= element(1, RS),
tuple_size(Record) =:= element(2, RS)).

%% Two kinds of debug macros (depnds on what you need to debug)
%% -define(DBG(T), erlang:display({{self(), ?MODULE, ?LINE, ?FUNCTION_NAME}, T})).
%% -define(DBG(F, A), io:format("~w -> " ++ F ++ "~n", [?FUNCTION_NAME | A])).
%% -define(DBG(F), ?DBG(F, [])).


%%% ---------------------------------
Expand Down Expand Up @@ -1918,11 +1921,29 @@ do_getiflist2('inet' = _Backend, Socket) when is_port(Socket) ->
net_getiflist(Socket) ->
case socket:ioctl(Socket, gifconf) of
{ok, Interfaces} ->
{ok, [Name || #{name := Name} <- Interfaces]};
Names = [Name || #{name := Name,
addr := #{family := Fam}} <-
Interfaces, ((Fam =:= inet) orelse
(Fam =:= inet6))],
{ok, ensure_unique_names(Names)};
{error, _} = ERROR ->
ERROR
end.

ensure_unique_names(Names) ->
ensure_unique_names(Names, []).

ensure_unique_names([], Acc) ->
lists:reverse(Acc);
ensure_unique_names([Name|Names], Acc) ->
case lists:member(Name, Acc) of
true ->
ensure_unique_names(Names, Acc);
false ->
ensure_unique_names(Names, [Name|Acc])
end.


inet_getiflist(Socket) ->
prim_inet:getiflist(Socket).

Expand Down
Loading

0 comments on commit 58cd1af

Please sign in to comment.