mirror of
https://gitlab.com/sortix/sortix.git
synced 2023-02-13 20:55:38 -05:00
Add if_nameindex(3).
This commit is contained in:
parent
2ef6804ead
commit
3997116656
7 changed files with 256 additions and 0 deletions
|
@ -412,6 +412,10 @@ netdb/getservent.o \
|
|||
netdb/setnetent.o \
|
||||
netdb/setprotoent.o \
|
||||
netdb/setservent.o \
|
||||
net/if/if_freenameindex.o \
|
||||
net/if/if_indextoname.o \
|
||||
net/if/if_nameindex.o \
|
||||
net/if/if_nametoindex.o \
|
||||
poll/poll.o \
|
||||
poll/ppoll.o \
|
||||
psctl/psctl.o \
|
||||
|
|
|
@ -74,4 +74,23 @@ struct if_config
|
|||
};
|
||||
#endif
|
||||
|
||||
struct if_nameindex
|
||||
{
|
||||
unsigned int if_index;
|
||||
char* if_name;
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void if_freenameindex(struct if_nameindex*);
|
||||
char* if_indextoname(unsigned int, char*);
|
||||
struct if_nameindex* if_nameindex(void);
|
||||
unsigned int if_nametoindex(const char*);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
28
libc/net/if/if_freenameindex.c
Normal file
28
libc/net/if/if_freenameindex.c
Normal file
|
@ -0,0 +1,28 @@
|
|||
/*
|
||||
* Copyright (c) 2016 Jonas 'Sortie' Termansen.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
* net/if/if_freenameindex.c
|
||||
* Free list of network interfaces.
|
||||
*/
|
||||
|
||||
#include <net/if.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
void if_freenameindex(struct if_nameindex* ifs)
|
||||
{
|
||||
for ( size_t i = 0; ifs[i].if_name; i++ )
|
||||
free(ifs[i].if_name);
|
||||
free(ifs);
|
||||
}
|
42
libc/net/if/if_indextoname.c
Normal file
42
libc/net/if/if_indextoname.c
Normal file
|
@ -0,0 +1,42 @@
|
|||
/*
|
||||
* Copyright (c) 2016 Jonas 'Sortie' Termansen.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
* net/if/if_indextoname.c
|
||||
* Get name of network interface by index.
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
#include <net/if.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
// TODO: This is better done with a dedicated system call.
|
||||
char* if_indextoname(unsigned int ifindex, char* str)
|
||||
{
|
||||
struct if_nameindex* ifs = if_nameindex();
|
||||
if ( !ifs )
|
||||
return NULL;
|
||||
for ( size_t i = 0; ifs[i].if_index; i++ )
|
||||
{
|
||||
if ( ifs[i].if_index == ifindex )
|
||||
{
|
||||
strlcpy(str, ifs[i].if_name, IF_NAMESIZE);
|
||||
if_freenameindex(ifs);
|
||||
return str;
|
||||
}
|
||||
}
|
||||
if_freenameindex(ifs);
|
||||
return errno = ENXIO, (char*) NULL;
|
||||
}
|
119
libc/net/if/if_nameindex.c
Normal file
119
libc/net/if/if_nameindex.c
Normal file
|
@ -0,0 +1,119 @@
|
|||
/*
|
||||
* Copyright (c) 2016, 2017 Jonas 'Sortie' Termansen.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
* net/if/if_nameindex.c
|
||||
* Build list of network interfaces.
|
||||
*/
|
||||
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include <dirent.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <net/if.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
// TODO: Consider turning this into a system call to avoid a number of error
|
||||
// cases and work properly in chroots.
|
||||
struct if_nameindex* if_nameindex(void)
|
||||
{
|
||||
DIR* dir = opendir("/dev");
|
||||
if ( !dir )
|
||||
return NULL;
|
||||
struct if_nameindex* ifs = (struct if_nameindex*)
|
||||
reallocarray(NULL, sizeof(struct if_nameindex), 2);
|
||||
if ( !ifs )
|
||||
return closedir(dir), (struct if_nameindex*) NULL;
|
||||
size_t ifs_count = 0;
|
||||
size_t ifs_allocated = 2;
|
||||
ifs[ifs_count].if_index = 0;
|
||||
ifs[ifs_count].if_name = NULL;
|
||||
struct dirent* entry;
|
||||
while ( (errno = 0, entry = readdir(dir)) )
|
||||
{
|
||||
if ( entry->d_type != DT_UNKNOWN && entry->d_type != DT_CHR )
|
||||
continue;
|
||||
int fd = openat(dirfd(dir), entry->d_name, O_RDWR | O_NOFOLLOW);
|
||||
if ( fd < 0 )
|
||||
{
|
||||
int errnum = errno;
|
||||
if ( entry->d_type == DT_UNKNOWN )
|
||||
{
|
||||
struct stat st;
|
||||
if ( fstatat(dirfd(dir), entry->d_name, &st,
|
||||
AT_SYMLINK_NOFOLLOW) < 0 )
|
||||
{
|
||||
closedir(dir);
|
||||
if_freenameindex(ifs);
|
||||
return NULL;
|
||||
}
|
||||
if ( !S_ISCHR(st.st_mode) )
|
||||
continue;
|
||||
}
|
||||
if ( errnum == ELOOP || errnum == EACCES || errnum == EPERM )
|
||||
continue;
|
||||
closedir(dir);
|
||||
if_freenameindex(ifs);
|
||||
return NULL;
|
||||
}
|
||||
int type;
|
||||
struct if_info info;
|
||||
if ( (type = ioctl(fd, IOCGETTYPE)) < 0 ||
|
||||
IOC_TYPE(type) != IOC_TYPE_NETWORK_INTERFACE ||
|
||||
ioctl(fd, NIOC_GETINFO, &info) < 0 )
|
||||
{
|
||||
close(fd);
|
||||
continue;
|
||||
}
|
||||
close(fd);
|
||||
if ( ifs_count + 1 == ifs_allocated )
|
||||
{
|
||||
size_t new_allocated = 2 * ifs_allocated;
|
||||
struct if_nameindex* new_ifs = (struct if_nameindex*)
|
||||
reallocarray(ifs, sizeof(struct if_nameindex), new_allocated);
|
||||
if ( !new_ifs )
|
||||
{
|
||||
closedir(dir);
|
||||
if_freenameindex(ifs);
|
||||
return NULL;
|
||||
}
|
||||
ifs = new_ifs;
|
||||
ifs_allocated = new_allocated;
|
||||
}
|
||||
char* name = strdup(entry->d_name);
|
||||
if ( !name )
|
||||
{
|
||||
closedir(dir);
|
||||
if_freenameindex(ifs);
|
||||
return NULL;
|
||||
}
|
||||
ifs[ifs_count].if_index = info.linkid;
|
||||
ifs[ifs_count].if_name = name;
|
||||
ifs_count++;
|
||||
ifs[ifs_count].if_index = 0;
|
||||
ifs[ifs_count].if_name = NULL;
|
||||
}
|
||||
if ( errno )
|
||||
{
|
||||
closedir(dir);
|
||||
if_freenameindex(ifs);
|
||||
return NULL;
|
||||
}
|
||||
closedir(dir);
|
||||
return ifs;
|
||||
}
|
43
libc/net/if/if_nametoindex.c
Normal file
43
libc/net/if/if_nametoindex.c
Normal file
|
@ -0,0 +1,43 @@
|
|||
/*
|
||||
* Copyright (c) 2016 Jonas 'Sortie' Termansen.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
* net/if/if_nametoindex.c
|
||||
* Get index of network interface by name.
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
#include <net/if.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
// TODO: This is better done with a dedicated system call.
|
||||
// TODO: Or at least the name can be looked up directly in /dev.
|
||||
unsigned int if_nametoindex(const char* name)
|
||||
{
|
||||
struct if_nameindex* ifs = if_nameindex();
|
||||
if ( !ifs )
|
||||
return NULL;
|
||||
for ( size_t i = 0; ifs[i].if_index; i++ )
|
||||
{
|
||||
if ( !strcmp(ifs[i].if_name, name) )
|
||||
{
|
||||
unsigned int result = ifs[i].if_index;
|
||||
if_freenameindex(ifs);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
if_freenameindex(ifs);
|
||||
return 0;
|
||||
}
|
|
@ -330,6 +330,7 @@ temporarily fail with
|
|||
.Xr getsockopt 2 ,
|
||||
.Xr ioctl 2 ,
|
||||
.Xr setsockopt 2 ,
|
||||
.Xr if_nameindex 3 ,
|
||||
.Xr arp 4 ,
|
||||
.Xr ether 4 ,
|
||||
.Xr inet 4 ,
|
||||
|
|
Loading…
Reference in a new issue