Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 7 additions & 5 deletions browser/components/enterprise/modules/ConsoleClient.sys.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -473,15 +473,17 @@ export const ConsoleClient = {
* @returns {DevicePosture} devicePosture
*/
_collectDevicePosture() {
Cc["@mozilla.org/network/network-link-service;1"]
.createInstance()
.QueryInterface(Ci.nsINetworkLinkService);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have seen cases locally while hacking where the instance may not be started, but I'm not sure this is required

const networkInterfaces = Cc["@mozilla.org/network/network-link-service;1"]
.getService()
.QueryInterface(Ci.nsINetworkLinkService).networkInterfaces;
const devicePosturePayload = {
os: lazy.TelemetryEnvironment.currentEnvironment.system.os,
security: lazy.TelemetryEnvironment.currentEnvironment.system.sec,
build: lazy.TelemetryEnvironment.currentEnvironment.build,
// TODO: Client posture IP addr is P2, to be filled later.
network: {
ipv4: null,
ipv6: null,
},
network: networkInterfaces,
};
return devicePosturePayload;
},
Expand Down
13 changes: 13 additions & 0 deletions netwerk/base/moz.build
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ XPIDL_SOURCES += [
"nsINetworkConnectivityService.idl",
"nsINetworkInfoService.idl",
"nsINetworkInterceptController.idl",
"nsINetworkInterface.idl",
"nsINetworkLinkService.idl",
"nsINetworkPredictor.idl",
"nsINetworkPredictorVerifier.idl",
Expand Down Expand Up @@ -139,6 +140,7 @@ EXPORTS += [
"nsInputStreamPump.h",
"nsMIMEInputStream.h",
"nsNetUtil.h",
"nsNetworkInterface.h",
"nsReadLine.h",
"nsSerializationHelper.h",
"nsSimpleNestedURI.h",
Expand Down Expand Up @@ -257,6 +259,17 @@ UNIFIED_SOURCES += [
"TRRLoadInfo.cpp",
]

if CONFIG["MOZ_ENTERPRISE"]:
if CONFIG["MOZ_WIDGET_TOOLKIT"] == "windows":
# netwerk/base/nsProtocolProxyService.cpp(736,10): error: no member named 'u' in 'PRIPv6Addr'
SOURCES += [
"nsNetworkInterface.cpp",
]
else:
UNIFIED_SOURCES += [
"nsNetworkInterface.cpp",
]

if CONFIG["FUZZING"]:
SOURCES += [
"FuzzyLayer.cpp",
Expand Down
28 changes: 28 additions & 0 deletions netwerk/base/nsINetworkInterface.idl
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/* vim: et ts=4 sw=4 tw=80
*/
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#include "nsISupports.idl"
interface nsINetAddr;

/**
* nsINetworkInterface
*
* This interface represents network interface informations
* - interface name
* - interface IP addresses
* - interface MAC
* - interface gateways
*/
[scriptable, uuid(1e3b9710-9118-4bc4-af4e-5cc166d64750)]
interface nsINetworkInterface : nsISupports
{
readonly attribute ACString name;
readonly attribute ACString mac;
readonly attribute Array<ACString> gwv4;
readonly attribute Array<ACString> gwv6;
readonly attribute Array<ACString> ipv4;
readonly attribute Array<ACString> ipv6;
};
5 changes: 4 additions & 1 deletion netwerk/base/nsINetworkLinkService.idl
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

#include "nsISupports.idl"
interface nsINetAddr;
interface nsINetworkInterface;

%{ C++
#include "nsTArrayForwardDeclare.h"
Expand All @@ -21,7 +22,7 @@ native NetAddr(mozilla::net::NetAddr);
/**
* Network link status monitoring service.
*/
[scriptable, uuid(103e5293-77b3-4b70-af59-6e9e4a1f994a)]
[scriptable, uuid(8ae30927-9dc9-49bd-ad82-7956861a93ce)]
interface nsINetworkLinkService : nsISupports
{
/* Link type constants */
Expand Down Expand Up @@ -88,6 +89,8 @@ interface nsINetworkLinkService : nsISupports
*/
readonly attribute unsigned long platformDNSIndications;

readonly attribute Array<nsINetworkInterface> networkInterfaces;

%{C++
static bool HasNonLocalIPv6Address();
%}
Expand Down
279 changes: 279 additions & 0 deletions netwerk/base/nsNetworkInterface.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,279 @@
/* vim: et ts=2 sw=2 tw=80
*/
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#include "nsNetworkInterface.h"
#include "nsString.h"
#include "mozilla/net/DNS.h"

NetworkInterface::NetworkInterface(const NetworkInterface& aIntf)
: mName(aIntf.mName), mMAC(aIntf.mMAC) {
mGwv4 = aIntf.GetGwv4();
mGwv6 = aIntf.GetGwv6();
mIpv4 = aIntf.GetIpv4();
mIpv6 = aIntf.GetIpv6();
};

void NetworkInterface::GetIP(const in_addr* aAddr, nsACString& aIpAddr) {
char addr[INET_ADDRSTRLEN];
addr[0] = 0;
inet_ntop(AF_INET, aAddr, addr, INET_ADDRSTRLEN);
aIpAddr.Assign(addr);
}

void NetworkInterface::GetIP(const in6_addr* aAddr, nsACString& aIpAddr) {
char addr[INET6_ADDRSTRLEN];
addr[0] = 0;
inet_ntop(AF_INET6, aAddr, addr, INET6_ADDRSTRLEN);
aIpAddr.Assign(addr);
}

void NetworkInterface::GetIP(const sockaddr_in* aAddr, nsACString& aIpAddr) {
GetIP(&aAddr->sin_addr, aIpAddr);
}

void NetworkInterface::GetIP(const sockaddr_in6* aAddr, nsACString& aIpAddr) {
GetIP(&aAddr->sin6_addr, aIpAddr);
}

void NetworkInterface::setMAC(const uint8_t* aAddr) {
mMAC = nsPrintfCString("%02x:%02x:%02x:%02x:%02x:%02x", aAddr[0], aAddr[1],
aAddr[2], aAddr[3], aAddr[4], aAddr[5]);
}

#if defined(XP_WIN)
NetworkInterface::NetworkInterface(PIP_ADAPTER_ADDRESSES aAdapter)
: mName(NS_ConvertUTF16toUTF8(aAdapter->FriendlyName)) {
uint8_t macAddress[6] = {0, 0, 0, 0, 0, 0};
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This needs to be MAX_ADAPTER_ADDRESS_LENGTH. Which is not 6 😄

memcpy(&macAddress, aAdapter->PhysicalAddress,
aAdapter->PhysicalAddressLength);
setMAC(macAddress);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What if PhysicalAddressLength was not 6? What if it is 0?


for (PIP_ADAPTER_UNICAST_ADDRESS pip = aAdapter->FirstUnicastAddress; pip;
pip = pip->Next) {
AddIP(&pip->Address);
}

for (IP_ADAPTER_GATEWAY_ADDRESS* pGw = aAdapter->FirstGatewayAddress; pGw;
pGw = pGw->Next) {
AddGW(&pGw->Address);
}
}

void NetworkInterface::AddIP(SOCKET_ADDRESS* aSockAddr) {
nsCString ip;

if (aSockAddr->lpSockaddr->sa_family == AF_INET) {
GetIP(reinterpret_cast<sockaddr_in*>(aSockAddr->lpSockaddr), ip);
mIpv4.AppendElement(std::move(ip));
} else if (aSockAddr->lpSockaddr->sa_family == AF_INET6) {
GetIP(reinterpret_cast<sockaddr_in6*>(aSockAddr->lpSockaddr), ip);
mIpv6.AppendElement(std::move(ip));
}
}

void NetworkInterface::AddGW(SOCKET_ADDRESS* aSockAddr) {
nsCString ip;

if (aSockAddr->lpSockaddr->sa_family == AF_INET) {
GetIP(reinterpret_cast<sockaddr_in*>(aSockAddr->lpSockaddr), ip);
mGwv4.AppendElement(std::move(ip));
} else if (aSockAddr->lpSockaddr->sa_family == AF_INET6) {
GetIP(reinterpret_cast<sockaddr_in6*>(aSockAddr->lpSockaddr), ip);
mGwv6.AppendElement(std::move(ip));
}
}
#endif // defined(XP_WIN)

#if defined(XP_LINUX)
NetworkInterface::NetworkInterface(const nsAutoCString aName,
const uint8_t* aMac)
: mName(aName) {
setMAC(aMac);
}

void NetworkInterface::AddIP(const struct in_addr* aAddr) {
nsCString ip;
GetIP(aAddr, ip);
mIpv4.AppendElement(std::move(ip));
}

void NetworkInterface::AddIP(const struct in6_addr* aAddr) {
nsCString ip;
GetIP(aAddr, ip);
mIpv6.AppendElement(std::move(ip));
}

void NetworkInterface::AddGW(const struct in_addr* aAddr) {
nsCString ip;
GetIP(aAddr, ip);
mGwv4.AppendElement(std::move(ip));
}

void NetworkInterface::AddGW(const struct in6_addr* aAddr) {
nsCString ip;
GetIP(aAddr, ip);
mGwv6.AppendElement(std::move(ip));
}
#endif

#if defined(XP_MACOSX)
NetworkInterface::NetworkInterface(
const char* aName,
nsTHashMap<nsCString, nsTArray<std::pair<int, nsCString>>>& aRoutes,
struct ifaddrs* aIfap)
: mName(aName) {
// setMAC(aMac);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes? No? Needed or not? I guess not because it's done explicitly below?


const auto& routingEntry = aRoutes.Lookup(Name());
if (routingEntry) {
for (const auto& ipAddrPair : *routingEntry) {
if (ipAddrPair.first == AF_INET) {
AddGWv4(std::move(ipAddrPair.second));
} else if (ipAddrPair.first == AF_INET6) {
AddGWv6(std::move(ipAddrPair.second));
}
}
}

for (struct ifaddrs* ifa = aIfap; ifa; ifa = ifa->ifa_next) {
if (ifa->ifa_addr == NULL) {
continue;
}

if (strcmp(aName, ifa->ifa_name) != 0) {
continue;
}

if (AF_INET6 == ifa->ifa_addr->sa_family) {
AddIP((struct sockaddr_in6*)ifa->ifa_addr);
} else if (AF_INET == ifa->ifa_addr->sa_family) {
AddIP((struct sockaddr_in*)ifa->ifa_addr);
}

if (AF_LINK == ifa->ifa_addr->sa_family) {
setMAC((struct sockaddr_dl*)ifa->ifa_addr);
}
}
}

void NetworkInterface::AddIP(const struct sockaddr_in* aAddr) {
nsCString ip;
GetIP(aAddr, ip);
mIpv4.AppendElement(std::move(ip));
}

void NetworkInterface::AddIP(const struct sockaddr_in6* aAddr) {
nsCString ip;
GetIP(aAddr, ip);
mIpv6.AppendElement(std::move(ip));
}

void NetworkInterface::AddGWv4(const nsACString& aIp) {
mGwv4.AppendElement(std::move(aIp));
}

void NetworkInterface::AddGWv6(const nsACString& aIp) {
mGwv6.AppendElement(std::move(aIp));
}

void NetworkInterface::setMAC(struct sockaddr_dl* aLink) {
if (aLink) {
uint8_t mac_addr[aLink->sdl_alen];
memcpy(mac_addr, aLink->sdl_data + aLink->sdl_nlen, aLink->sdl_alen);
setMAC(mac_addr);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably same issue that this can't cope with unexpected lengths.

}
}

bool getRoutesForNetworkInterfaces(
struct rt_msghdr* rtm,
nsTHashMap<nsCString, nsTArray<std::pair<int, nsCString>>>& ifNameAndIp,
bool skipDstCheck) {
struct sockaddr* sa;
if ((rtm->rtm_addrs & (RTA_DST | RTA_GATEWAY)) != (RTA_DST | RTA_GATEWAY)) {
return false;
}

sa = reinterpret_cast<struct sockaddr*>(rtm + 1);

struct sockaddr* destination =
reinterpret_cast<struct sockaddr*>((char*)sa + RTAX_DST * SA_SIZE(sa));
if (!destination) {
return false;
}

if (destination->sa_family != AF_INET && destination->sa_family != AF_INET6) {
return false;
}

struct sockaddr* gateway = reinterpret_cast<struct sockaddr*>(
(char*)sa + RTAX_GATEWAY * SA_SIZE(sa));
if (!gateway) {
return false;
}

nsCString ipAddr;
if (gateway->sa_family == AF_INET) {
NetworkInterface::GetIP(
reinterpret_cast<const struct sockaddr_in*>(gateway), ipAddr);
} else if (gateway->sa_family == AF_INET6) {
NetworkInterface::GetIP(
reinterpret_cast<const struct sockaddr_in6*>(gateway), ipAddr);
}

char buf[IFNAMSIZ] = {0};
char* if_name = if_indextoname(rtm->rtm_index, buf);
if (!if_name) {
LOG(("getRoutes: AF_INET if_indextoname failed"));
return false;
}

nsCString ifName = nsCString(if_name);
std::pair<int, nsCString> ipAddrPair =
std::make_pair(destination->sa_family, ipAddr);

auto& ifNameEntry = ifNameAndIp.LookupOrInsert(ifName);
LOG(("getRoutes: ifNameEntry for %s", ifName.get()));
if (!ifNameEntry.Contains(ipAddrPair)) {
LOG(("getRoutes: ifNameEntry for %s does not contain %s, adding",
ifName.get(), ipAddr.get()));
ifNameEntry.AppendElement(ipAddrPair);
}

return true;
}
#endif // defined(XP_MACOSX)

NS_IMPL_ISUPPORTS(nsNetworkInterface, nsINetworkInterface)

NS_IMETHODIMP nsNetworkInterface::GetName(nsACString& aName) {
aName = mIntf.Name();
return NS_OK;
}

NS_IMETHODIMP nsNetworkInterface::GetMac(nsACString& aMac) {
aMac = mIntf.Mac();
return NS_OK;
}

NS_IMETHODIMP nsNetworkInterface::GetGwv4(nsTArray<nsCString>& aGwv4) {
aGwv4 = mIntf.GetGwv4();
return NS_OK;
}

NS_IMETHODIMP nsNetworkInterface::GetGwv6(nsTArray<nsCString>& aGwv6) {
aGwv6 = mIntf.GetGwv6();
return NS_OK;
}

NS_IMETHODIMP nsNetworkInterface::GetIpv4(nsTArray<nsCString>& aIpv4) {
aIpv4 = mIntf.GetIpv4();
return NS_OK;
}

NS_IMETHODIMP nsNetworkInterface::GetIpv6(nsTArray<nsCString>& aIpv6) {
aIpv6 = mIntf.GetIpv6();
return NS_OK;
}
Loading