Added support for SIOCGIFBRDADDR, SIOCGIFDSTADDR, SIOCGIFFLAGS

This commit is contained in:
Fabrizio Bertocci 2021-05-23 16:32:40 -04:00
parent 1b8776dea7
commit d5a839c724
4 changed files with 54 additions and 23 deletions

View file

@ -32,7 +32,10 @@
* The ifc_len is an input/output parameter: set it to the total size of
* the ifcu_buf (ifcu_req) buffer on input.
*/
int ioctl_default(int, uint64_t, void *) hidden;
int ioctl_siocgifconf_nt(int, struct ifconf *) hidden;
int ioctl_siocgifaddr_nt(int, struct ifconf *) hidden;
static int ioctl_siocgifconf_sysv(int fd, struct ifconf *ifc) {
if (IsBsd()) {
@ -93,13 +96,16 @@ static int ioctl_siocgifconf_sysv(int fd, struct ifconf *ifc) {
}
}
static int ioctl_siocgifaddr_sysv(int fd, struct ifreq *ifr) {
/* Used for all the ioctl that returns sockaddr structure that
* requires adjustment between Linux and BSD
*/
static int ioctl_siocgifaddr_sysv(int fd, uint64_t op, struct ifreq *ifr) {
int i;
if (IsBsd()) {
sockaddr2bsd(&ifr->ifr_addr);
}
if ((i = sys_ioctl(fd, SIOCGIFADDR, ifr)) < 0) {
if ((i = sys_ioctl(fd, op, ifr)) < 0) {
return -1;
}
if (IsBsd()) {
@ -108,21 +114,6 @@ static int ioctl_siocgifaddr_sysv(int fd, struct ifreq *ifr) {
return 0;
}
static int ioctl_siocgifnetmask_sysv(int fd, struct ifreq *ifr) {
int i;
if (IsBsd()) {
sockaddr2bsd(&ifr->ifr_netmask);
}
if ((i = sys_ioctl(fd, SIOCGIFNETMASK, ifr)) < 0) {
return -1;
}
if (IsBsd()) {
sockaddr2linux(&ifr->ifr_netmask);
}
return 0;
}
/**
* Returns information about network interfaces.
*
@ -139,7 +130,7 @@ int ioctl_siocgifconf(int fd, void *ifc) {
int ioctl_siocgifaddr(int fd, void *ifr) {
if (!IsWindows()) {
return ioctl_siocgifaddr_sysv(fd, (struct ifreq *)ifr);
return ioctl_siocgifaddr_sysv(fd, SIOCGIFADDR, (struct ifreq *)ifr);
} else {
return enotsup();
//return ioctl_siocgifaddr_nt(fd, ifc);
@ -148,9 +139,37 @@ int ioctl_siocgifaddr(int fd, void *ifr) {
int ioctl_siocgifnetmask(int fd, void *ifr) {
if (!IsWindows()) {
return ioctl_siocgifnetmask_sysv(fd, (struct ifreq *)ifr);
return ioctl_siocgifaddr_sysv(fd, SIOCGIFNETMASK, (struct ifreq *)ifr);
} else {
return enotsup();
//return ioctl_siocgifaddr_nt(fd, ifc);
//return ioctl_siocgifnetmask_nt(fd, ifc);
}
}
int ioctl_siocgifbrdaddr(int fd, void *ifr) {
if (!IsWindows()) {
return ioctl_siocgifaddr_sysv(fd, SIOCGIFBRDADDR, (struct ifreq *)ifr);
} else {
return enotsup();
//return ioctl_siocgifbrdaddr_nt(fd, ifc);
}
}
int ioctl_siocgifdstaddr(int fd, void *ifr) {
if (!IsWindows()) {
return ioctl_siocgifaddr_sysv(fd, SIOCGIFDSTADDR, (struct ifreq *)ifr);
} else {
return enotsup();
//return ioctl_siocgifbrdaddr_nt(fd, ifc);
}
}
int ioctl_siocgifflags(int fd, void *ifr) {
if (!IsWindows()) {
/* Both BSD and Linux are for once compatible here... */
return ioctl_default(fd, SIOCGIFFLAGS, ifr);
} else {
return enotsup();
//return ioctl_siocgifflags_nt(fd, ifc);
}
}

View file

@ -31,6 +31,9 @@ int ioctl(int, uint64_t, void *);
if (CMP(request, SIOCGIFCONF)) return ioctl_siocgifconf(FD, MEMORY); \
if (CMP(request, SIOCGIFADDR)) return ioctl_siocgifaddr(FD, MEMORY); \
if (CMP(request, SIOCGIFNETMASK)) return ioctl_siocgifnetmask(FD, MEMORY); \
if (CMP(request, SIOCGIFBRDADDR)) return ioctl_siocgifbrdaddr(FD, MEMORY); \
if (CMP(request, SIOCGIFDSTADDR)) return ioctl_siocgifdstaddr(FD, MEMORY); \
if (CMP(request, SIOCGIFFLAGS)) return ioctl_siocgifflags(FD, MEMORY); \
} while (0)
/*
@ -47,7 +50,10 @@ int ioctl_tiocswinsz(int, void *);
int ioctl_tiocswinsz_nt(int, void *);
int ioctl_siocgifconf(int, void *);
int ioctl_siocgifaddr(int, void *);
int ioctl_siocgifdstaddr(int, void *);
int ioctl_siocgifnetmask(int, void *);
int ioctl_siocgifbrdaddr(int, void *);
int ioctl_siocgifflags(int, void *);
int ioctl_default(int, uint64_t, void *);
forceinline int ioctl_dispatch(int fd, uint64_t request, void *memory) {

View file

@ -71,6 +71,8 @@ struct ifreq_bsd {
*/
struct sockaddr_bsd ifru_addr;
struct sockaddr_bsd ifru_netmask;
struct sockaddr_bsd ifru_dstaddr;
struct sockaddr_bsd ifru_broadaddr;
short ifru_flags;
char ifru_pad[16]; /* used as padding */
} ifr_ifru;

View file

@ -108,9 +108,11 @@ struct ifreq {
} ifr_ifrn;
union {
struct sockaddr ifru_addr;
struct sockaddr ifru_netmask;
short ifru_flags;
struct sockaddr ifru_addr; /* SIOCGIFADDR */
struct sockaddr ifru_dstaddr; /* SIOCGIFDSTADDR */
struct sockaddr ifru_netmask; /* SIOCGIFNETMASK */
struct sockaddr ifru_broadaddr; /* SIOCGIFBRDADDR */
short ifru_flags; /* SIOCGIFFLAGS */
char ifru_pad[24]; /* ifru_map is the largest, just pad */
} ifr_ifru;
};
@ -118,6 +120,8 @@ struct ifreq {
#define ifr_name ifr_ifrn.ifrn_name /* interface name */
#define ifr_addr ifr_ifru.ifru_addr /* address */
#define ifr_netmask ifr_ifru.ifru_netmask /* netmask */
#define ifr_broadaddr ifr_ifru.ifru_broadaddr /* broadcast address */
#define ifr_dstaddr ifr_ifru.ifru_dstaddr /* destination address */
#define ifr_flags ifr_ifru.ifru_flags /* flags */
#define _IOT_ifreq _IOT(_IOTS(char),IFNAMSIZ,_IOTS(char),16,0,0)