1 /* Find network interface names and index numbers. Hurd version.
2 Copyright (C) 2000-2024 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
5 The GNU C Library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
10 The GNU C Library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
15 You should have received a copy of the GNU Lesser General Public
16 License along with the GNU C Library; if not, see
17 <https://www.gnu.org/licenses/>. */
22 #include <sys/ioctl.h>
26 #include <hurd/ioctl.h>
27 #include <hurd/pfinet.h>
29 /* Return the interface index corresponding to interface IFNAME.
30 On error, return 0. */
32 __if_nametoindex (const char *ifname
)
35 int fd
= __socket (AF_INET
, SOCK_DGRAM
, 0);
40 if (strlen (ifname
) >= IFNAMSIZ
)
41 return __hurd_fail (ENODEV
), 0;
43 strncpy (ifr
.ifr_name
, ifname
, IFNAMSIZ
);
44 if (__ioctl (fd
, SIOCGIFINDEX
, &ifr
) < 0)
46 int saved_errno
= errno
;
48 if (saved_errno
== EINVAL
|| saved_errno
== ENOTTY
)
53 return ifr
.ifr_ifindex
;
55 libc_hidden_def (__if_nametoindex
)
56 weak_alias (__if_nametoindex
, if_nametoindex
)
57 libc_hidden_weak (if_nametoindex
)
59 /* Free the structure IFN returned by if_nameindex. */
61 __if_freenameindex (struct if_nameindex
*ifn
)
63 struct if_nameindex
*ptr
= ifn
;
64 while (ptr
->if_name
|| ptr
->if_index
)
71 libc_hidden_def (__if_freenameindex
)
72 weak_alias (__if_freenameindex
, if_freenameindex
)
73 libc_hidden_weak (if_freenameindex
)
75 /* Return an array of if_nameindex structures, one for each network
76 interface present, plus one indicating the end of the array. On
77 error, return NULL. */
84 int fd
= __socket (AF_INET
, SOCK_DGRAM
, 0);
87 struct if_nameindex
*idx
= NULL
;
94 server
= _hurd_socket_server (PF_INET
, 0);
95 if (server
== MACH_PORT_NULL
)
99 mach_msg_type_number_t len
= sizeof data
;
100 err
= __pfinet_siocgifconf (server
, -1, &ifc
.ifc_buf
, &len
);
101 if (err
== MACH_SEND_INVALID_DEST
|| err
== MIG_SERVER_DIED
)
103 /* On the first use of the socket server during the operation,
104 allow for the old server port dying. */
105 server
= _hurd_socket_server (PF_INET
, 1);
106 if (server
== MACH_PORT_NULL
)
108 err
= __pfinet_siocgifconf (server
, -1, &ifc
.ifc_buf
, &len
);
114 nifs
= len
/ sizeof (struct ifreq
);
117 idx
= malloc ((nifs
+ 1) * sizeof (struct if_nameindex
));
124 for (i
= 0; i
< nifs
; ++i
)
126 struct ifreq
*ifr
= &ifc
.ifc_req
[i
];
127 idx
[i
].if_name
= __strdup (ifr
->ifr_name
);
128 if (idx
[i
].if_name
== NULL
129 || __ioctl (fd
, SIOCGIFINDEX
, ifr
) < 0)
134 for (j
= 0; j
< i
; ++j
)
135 free (idx
[j
].if_name
);
141 else if (err
== ENOMEM
)
145 idx
[i
].if_index
= ifr
->ifr_ifindex
;
149 idx
[i
].if_name
= NULL
;
153 if (data
!= ifc
.ifc_buf
)
154 __vm_deallocate (__mach_task_self (), (vm_address_t
) ifc
.ifc_buf
,
159 weak_alias (__if_nameindex
, if_nameindex
)
160 libc_hidden_weak (if_nameindex
)
162 /* Store the name of the interface corresponding to index IFINDEX in
163 IFNAME (which has space for at least IFNAMSIZ characters). Return
164 IFNAME, or NULL on error. */
166 __if_indextoname (unsigned int ifindex
, char ifname
[IF_NAMESIZE
])
169 int fd
= __socket (AF_INET
, SOCK_DGRAM
, 0);
174 ifr
.ifr_ifindex
= ifindex
;
175 if (__ioctl (fd
, SIOCGIFNAME
, &ifr
) < 0)
177 int saved_errno
= errno
;
179 if (saved_errno
== EINVAL
|| saved_errno
== ENOTTY
)
180 __hurd_fail (ENOSYS
);
181 else if (saved_errno
== ENODEV
)
186 return strncpy (ifname
, ifr
.ifr_name
, IFNAMSIZ
);
188 weak_alias (__if_indextoname
, if_indextoname
)
189 libc_hidden_weak (if_indextoname
)
193 __protocol_available (int *have_inet
, int *have_inet6
)
195 *have_inet
= _hurd_socket_server (PF_INET
, 0) != MACH_PORT_NULL
;
196 *have_inet6
= _hurd_socket_server (PF_INET6
, 0) != MACH_PORT_NULL
;