Skip to content

Commit

Permalink
DEV9: Improve logic for getting MacAddress
Browse files Browse the repository at this point in the history
  • Loading branch information
fjtrujy committed Apr 10, 2024
1 parent 91b0b16 commit 2adc08a
Showing 1 changed file with 84 additions and 21 deletions.
105 changes: 84 additions & 21 deletions pcsx2/DEV9/AdapterUtils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,22 +8,24 @@
#include "common/StringUtil.h"

#ifdef __POSIX__
#include <unistd.h>
#include <vector>
#include <fstream>
#include <net/if.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

#ifdef __linux__
#include <unistd.h>
#include <sys/ioctl.h>
#endif
#include <string.h>

#if defined(__FreeBSD__) || (__APPLE__)
#include <sys/types.h>
#include <net/if_dl.h>
#include <sys/param.h>
#include <sys/sysctl.h>
#include <sys/sockio.h>
#include <net/route.h>
#include <net/if_var.h>
#endif
#endif

Expand Down Expand Up @@ -244,30 +246,91 @@ std::optional<MAC_Address> AdapterUtils::GetAdapterMAC(Adapter* adapter)

return std::nullopt;
}
#elif defined(__POSIX__)
#ifdef __linux__
#else
std::optional<MAC_Address> AdapterUtils::GetAdapterMAC(Adapter* adapter)
{
struct ifreq ifr;
strcpy(ifr.ifr_name, adapter->ifa_name);

int fd = socket(AF_INET, SOCK_DGRAM, 0);
int ret = ioctl(fd, SIOCGIFHWADDR, &ifr);
close(fd);
int sd;
struct ifreq ifr, *ifrp;
struct ifconf ifc;
char buf[1024];
int n, i;
MAC_Address macAddr;
#ifdef AF_LINK
struct sockaddr_dl *sdlp;
#endif

if (ret == 0)
return *(MAC_Address*)ifr.ifr_hwaddr.sa_data;
/*
* BSD 4.4 defines the size of an ifreq to be
* max(sizeof(ifreq), sizeof(ifreq.ifr_name)+ifreq.ifr_addr.sa_len
* However, under earlier systems, sa_len isn't present, so the size is
* just sizeof(struct ifreq)
*/
#ifdef HAVE_SA_LEN
#ifndef max
#define max(a,b) ((a) > (b) ? (a) : (b))
#endif
#define ifreq_size(i) max(sizeof(struct ifreq),\
sizeof((i).ifr_name)+(i).ifr_addr.sa_len)
#else
#define ifreq_size(i) sizeof(struct ifreq)
#endif /* HAVE_SA_LEN*/

return std::nullopt;
}
sd = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP);
if (sd < 0)
{
return std::nullopt;
}
memset(buf, 0, sizeof(buf));
ifc.ifc_len = sizeof(buf);
ifc.ifc_buf = buf;
if (ioctl (sd, SIOCGIFCONF, (char *)&ifc) < 0)

Check notice on line 286 in pcsx2/DEV9/AdapterUtils.cpp

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

pcsx2/DEV9/AdapterUtils.cpp#L286

C-style pointer casting
{
close(sd);
return std::nullopt;
}
n = ifc.ifc_len;
for (i = 0; i < n; i+= ifreq_size(*ifrp) )
{
ifrp = (struct ifreq *)((char *) ifc.ifc_buf+i);

Check notice on line 294 in pcsx2/DEV9/AdapterUtils.cpp

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

pcsx2/DEV9/AdapterUtils.cpp#L294

C-style pointer casting
strncpy(ifr.ifr_name, ifrp->ifr_name, IFNAMSIZ);
#ifdef SIOCGIFHWADDR
if (ioctl(sd, SIOCGIFHWADDR, &ifr) < 0)
continue;
memcpy(&macAddr, &ifr.ifr_hwaddr.sa_data, 6);
#else
std::optional<MAC_Address> AdapterUtils::GetAdapterMAC(Adapter* adapter)
{
Console.Error("DEV9: Unsupported OS, can't get MAC address");
#ifdef SIOCGENADDR
if (ioctl(sd, SIOCGENADDR, &ifr) < 0)
continue;
memcpy(&macAddr, &ifr.ifr_enaddr, 6);
#else
#ifdef AF_LINK
sdlp = (struct sockaddr_dl *) &ifrp->ifr_addr;

Check notice on line 307 in pcsx2/DEV9/AdapterUtils.cpp

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

pcsx2/DEV9/AdapterUtils.cpp#L307

C-style pointer casting
if ((sdlp->sdl_family != AF_LINK) || (sdlp->sdl_alen != 6))
continue;
memcpy(&macAddr, &sdlp->sdl_data[sdlp->sdl_nlen], 6);
#else
/*
* XXX we don't have a way of getting the hardware
* address
*/
Console.Error("DEV9: Unsupported OS, can't get MAC address");
close(sd);
return std::nullopt
#endif /* AF_LINK */
#endif /* SIOCGENADDR */
#endif /* SIOCGIFHWADDR */
if (!macAddr[0] && !macAddr[1] && !macAddr[2] && !macAddr[3] && !macAddr[4] && !macAddr[5])
continue;

// We have a valid MAC address.
close(sd);
return macAddr;

Check notice on line 327 in pcsx2/DEV9/AdapterUtils.cpp

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

pcsx2/DEV9/AdapterUtils.cpp#L327

Consecutive return, break, continue, goto or throw statements are unnecessary.
}
close(sd);
Console.Error("DEV9: Unsupported OS, can't get network features");
return std::nullopt;
}
#endif
#endif

// AdapterIP.
#ifdef _WIN32
Expand Down Expand Up @@ -376,7 +439,7 @@ std::vector<IP_Address> AdapterUtils::GetGateways(Adapter* adapter)
}
return collection;
}
#elif defined(__FreeBSD__) || (__APPLE__)
#elif defined(__FreeBSD__) || defined(__APPLE__)
std::vector<IP_Address> AdapterUtils::GetGateways(Adapter* adapter)
{
if (adapter == nullptr)
Expand Down

0 comments on commit 2adc08a

Please sign in to comment.