mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-08-03 16:30:29 +00:00
Initial implementation of ioctl SIOCGIFCONF. Untested for most of the platforms yet.
This commit is contained in:
parent
f40f97bd07
commit
187eb9ae41
5 changed files with 177 additions and 0 deletions
61
libc/calls/ioctl-siocgifconf-nt.c
Normal file
61
libc/calls/ioctl-siocgifconf-nt.c
Normal file
|
@ -0,0 +1,61 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ Permission to use, copy, modify, and/or 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. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/sysv/consts/o.h"
|
||||
#include "libc/sock/sock.h"
|
||||
#include "libc/sock/internal.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
#include "libc/nt/winsock.h"
|
||||
|
||||
// TODO: Remove me
|
||||
#include "libc/stdio/stdio.h"
|
||||
|
||||
#define MAX_INTERFACES 32
|
||||
|
||||
/* Reference:
|
||||
* - Description of ioctls: https://docs.microsoft.com/en-us/windows/win32/winsock/winsock-ioctls
|
||||
* - Structure INTERFACE_INFO: https://docs.microsoft.com/en-us/windows/win32/api/ws2ipdef/ns-ws2ipdef-interface_info
|
||||
* - WSAIoctl man page: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-wsaioctl
|
||||
* - Using SIOCGIFCONF in Win32: https://docs.microsoft.com/en-us/windows/win32/winsock/using-unix-ioctls-in-winsock
|
||||
*/
|
||||
|
||||
textwindows int ioctl_siocgifconf_nt(int fd, struct ifconf *ifc) {
|
||||
struct NtInterfaceInfo iflist[MAX_INTERFACES];
|
||||
uint32_t dwBytes;
|
||||
int ret;
|
||||
int i, count;
|
||||
|
||||
if (g_fds.p[fd].kind != kFdSocket) {
|
||||
return ebadf();
|
||||
}
|
||||
|
||||
ret = WSAIoctl(g_fds.p[fd].handle, kNtSioGetInterfaceList, NULL, 0, &iflist, sizeof(iflist), &dwBytes, NULL, NULL);
|
||||
if (ret == -1) {
|
||||
return __winsockerr();
|
||||
}
|
||||
|
||||
count = dwBytes / sizeof(struct NtInterfaceInfo);
|
||||
printf("CI> SIO_GET_INTERFACE_LIST success:\n");
|
||||
for (i = 0; i < count; ++i) {
|
||||
printf("CI>\t #i: %08x\n", i, iflist[i].iiAddress.sin_addr.s_addr);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
51
libc/calls/ioctl-siocgifconf.c
Normal file
51
libc/calls/ioctl-siocgifconf.c
Normal file
|
@ -0,0 +1,51 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ Permission to use, copy, modify, and/or 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. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/sock/sock.h"
|
||||
#include "libc/sock/internal.h"
|
||||
#include "libc/sysv/consts/sio.h"
|
||||
|
||||
int ioctl_siocgifconf_nt(int, struct ifconf *) hidden;
|
||||
|
||||
static int ioctl_siocgifconf_sysv(int fd, struct ifconf *ifc) {
|
||||
/* Same as the default for now... */
|
||||
return sys_ioctl(fd, SIOCGIFCONF, ifc);
|
||||
/*
|
||||
int rc;
|
||||
|
||||
if ((rc = sys_ioctl(fd, SIOCGIFCONF, &ifc)) != -1) {
|
||||
return rc;
|
||||
}
|
||||
return rc;
|
||||
*/
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns information about network interfaces.
|
||||
*
|
||||
* @see ioctl(fd, SIOCGIFCONF, tio) dispatches here
|
||||
*/
|
||||
int ioctl_siocgifconf(int fd, struct ifconf *ifc) {
|
||||
if (!IsWindows()) {
|
||||
return ioctl_siocgifconf_sysv(fd, ifc);
|
||||
} else {
|
||||
return ioctl_siocgifconf_nt(fd, ifc);
|
||||
}
|
||||
}
|
||||
|
|
@ -2,6 +2,7 @@
|
|||
#define COSMOPOLITAN_LIBC_CALLS_IOCTL_H_
|
||||
#include "libc/macros.internal.h"
|
||||
#include "libc/sysv/consts/termios.h"
|
||||
#include "libc/sysv/consts/sio.h"
|
||||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||
COSMOPOLITAN_C_START_
|
||||
|
||||
|
@ -27,6 +28,7 @@ int ioctl(int, uint64_t, void *);
|
|||
if (CMP(request, TCSETS)) return ioctl_tcsets(FD, REQUEST, MEMORY); \
|
||||
if (CMP(request, TCSETSW)) return ioctl_tcsets(FD, REQUEST, MEMORY); \
|
||||
if (CMP(request, TCSETSF)) return ioctl_tcsets(FD, REQUEST, MEMORY); \
|
||||
if (CMP(request, SIOCGIFCONF)) return ioctl_siocgifconf(FD, REQUEST, MEMORY); \
|
||||
} while (0)
|
||||
|
||||
int ioctl_tcgets(int, void *);
|
||||
|
@ -37,6 +39,7 @@ int ioctl_tiocgwinsz(int, void *);
|
|||
int ioctl_tiocgwinsz_nt(int, void *);
|
||||
int ioctl_tiocswinsz(int, void *);
|
||||
int ioctl_tiocswinsz_nt(int, void *);
|
||||
int ioctl_siocgifconf(int, uint64_t, void *);
|
||||
int ioctl_default(int, uint64_t, void *);
|
||||
|
||||
forceinline int ioctl_dispatch(int fd, uint64_t request, void *memory) {
|
||||
|
|
|
@ -85,6 +85,7 @@
|
|||
#define kNtSioTranslateHandle 0xC800000Du
|
||||
#define kNtSioUdpConnreset 0x9800000Cu
|
||||
#define kNtSioUdpNetreset 0x9800000Fu
|
||||
#define kNtSioGetInterfaceList 0x4008747fu /* _IOR('t', 127, ULONG) */
|
||||
|
||||
#define kNtNspNotifyImmediately 0
|
||||
#define kNtNspNotifyHwnd 1
|
||||
|
@ -311,6 +312,13 @@ struct NtFdSet {
|
|||
int64_t fd_array[64];
|
||||
};
|
||||
|
||||
struct NtInterfaceInfo {
|
||||
uint64_t iiFlags;
|
||||
struct sockaddr_in iiAddress;
|
||||
struct sockaddr_in iiBroadcastAddress;
|
||||
struct sockaddr_in iiNetmask;
|
||||
};
|
||||
|
||||
/**
|
||||
* Winsock2 prototypes.
|
||||
*
|
||||
|
|
|
@ -75,6 +75,60 @@ struct msghdr { /* Linux+NT ABI */
|
|||
uint32_t msg_flags; /* MSG_XXX */
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Structure used in SIOCGIFCONF request.
|
||||
* Used to retrieve interface configuration
|
||||
* for machine (useful for programs which
|
||||
* must know all networks accessible).
|
||||
*/
|
||||
struct ifconf {
|
||||
int ifc_len; /* size of buffer */
|
||||
union {
|
||||
char *ifcu_buf;
|
||||
struct ifreq *ifcu_req;
|
||||
} ifc_ifcu;
|
||||
};
|
||||
|
||||
/* Shortcuts to the ifconf buffer or ifreq array */
|
||||
#define ifc_buf ifc_ifcu.ifcu_buf /* buffer address */
|
||||
#define ifc_req ifc_ifcu.ifcu_req /* array of structures */
|
||||
|
||||
#define IFHWADDRLEN 6
|
||||
#define IF_NAMESIZE 16
|
||||
#define IFNAMSIZ IF_NAMESIZE
|
||||
struct ifreq {
|
||||
union {
|
||||
char ifrn_name[IFNAMSIZ]; /* Interface name, e.g. "en0". */
|
||||
} ifr_ifrn;
|
||||
|
||||
union {
|
||||
struct sockaddr ifru_addr;
|
||||
struct sockaddr ifru_dstaddr;
|
||||
struct sockaddr ifru_broadaddr;
|
||||
short int ifru_flags;
|
||||
int ifru_ivalue;
|
||||
int ifru_mtu;
|
||||
} ifr_ifru;
|
||||
};
|
||||
# define ifr_name ifr_ifrn.ifrn_name /* interface name */
|
||||
# define ifr_addr ifr_ifru.ifru_addr /* address */
|
||||
# define ifr_dstaddr ifr_ifru.ifru_dstaddr /* other end of p-p lnk */
|
||||
# define ifr_broadaddr ifr_ifru.ifru_broadaddr /* broadcast address */
|
||||
# define ifr_flags ifr_ifru.ifru_flags /* flags */
|
||||
# define ifr_metric ifr_ifru.ifru_ivalue /* metric */
|
||||
# define ifr_mtu ifr_ifru.ifru_mtu /* mtu */
|
||||
# define ifr_ifindex ifr_ifru.ifru_ivalue /* interface index */
|
||||
# define ifr_bandwidth ifr_ifru.ifru_ivalue /* link bandwidth */
|
||||
# define ifr_qlen ifr_ifru.ifru_ivalue /* queue length */
|
||||
# define _IOT_ifreq _IOT(_IOTS(char),IFNAMSIZ,_IOTS(char),16,0,0)
|
||||
# define _IOT_ifreq_short _IOT(_IOTS(char),IFNAMSIZ,_IOTS(short),1,0,0)
|
||||
# define _IOT_ifreq_int _IOT(_IOTS(char),IFNAMSIZ,_IOTS(int),1,0,0)
|
||||
|
||||
#define IFF_UP (1<<0)
|
||||
|
||||
|
||||
|
||||
const char *inet_ntop(int, const void *, char *, uint32_t);
|
||||
int inet_aton(const char *, struct in_addr *);
|
||||
int inet_pton(int, const char *, void *);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue