-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathDapNetworkMonitorDarwin.cpp
More file actions
166 lines (140 loc) · 5.59 KB
/
DapNetworkMonitorDarwin.cpp
File metadata and controls
166 lines (140 loc) · 5.59 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
#include "DapNetworkMonitorDarwin.h"
#include <QFileInfo>
#include <stdio.h>
#include <string.h>
#include <QProcess>
static void callbackForChangedInterfaces (const void* a_key, const void* a_value, void* a_context) {
qInfo() << "Key - " << a_key << " value - " << a_value; // There is no usefull information from this so far
}
void DapNetworkMonitorDarwin::cbMonitorNotification(SCDynamicStoreRef a_store, CFArrayRef a_changedKeys, void *a_info)
{
// Count of available names in ArrayRef
CFIndex nameCount = CFArrayGetCount( a_changedKeys );
//Iterate through the CFArrayRef and fill the vector
for( int i = 0; i < nameCount ; ++i )
{
CFStringRef l_sName = (CFStringRef)CFArrayGetValueAtIndex( a_changedKeys, i );
const char *l_cstrName = CFStringGetCStringPtr( l_sName , kCFStringEncodingMacRoman );
//qInfo() << "Interface " << l_cstrName << " is changed";
CFDictionaryRef __values = (CFDictionaryRef)SCDynamicStoreCopyValue(a_store, l_sName);
if (__values == NULL){
qWarning() << "Interface " << l_cstrName << " is undefined";
emit instance()->sigInterfaceUndefined();
return;
}
else{
qInfo() << "Defined new or changed interface " << l_cstrName;
}
CFDictionaryApplyFunction(__values, callbackForChangedInterfaces, NULL);
}
if (instance()->isTunGatewayDefinedInnerCheck())
emit instance()->sigTunGatewayDefined();
else if (instance()->isOtherGatewayDefinedInnerCheck())
//emit instance()->sigOtherGatewayDefined(); // TODO More deep check, because default gateway may be false route from wifi
emit instance()->sigOtherGatewayUndefined();
else {
emit instance()->sigTunGatewayUndefined();
instance()->handleNetworkFailure();
}
}
bool DapNetworkMonitorDarwin::handleNetworkFailure() {
qDebug() << "Attempting to recover network connectivity...";
QProcess process;
QString command = "sudo ifconfig en0 down && sudo ifconfig en0 up";
process.start(command);
process.waitForFinished();
if (process.exitStatus() == QProcess::NormalExit && process.exitCode() == 0) {
qDebug() << "Network interface en0 restarted successfully.";
} else {
qWarning() << "Failed to restart network interface en0:" << process.readAllStandardError();
}
emit sigInterfaceDefined();
return true;
}
DapNetworkMonitorDarwin::DapNetworkMonitorDarwin(QObject *parent):
DapNetworkMonitorAbstract(parent)
{
m_isTunGatewayDefined.store(true);
m_isInterfaceDefined.store(true);
m_isHostReachable.store(true);
m_isOtherGatewayDefined.store(true);
}
bool DapNetworkMonitorDarwin::isTunDriverInstalled() const
{
return true; // TODO make com.apple.developer.networking.networkextension entitlement check
}
bool DapNetworkMonitorDarwin::monitoringStart()
{
qDebug() << "Start network monitoring";
if(m_isMonitoringRunning == true) {
qWarning() << "Network monitoring already running";
}
if(dap_network_monitor_init(cbMonitorNotification) == 0) {
m_isMonitoringRunning = true;
}
return m_isMonitoringRunning;
}
bool DapNetworkMonitorDarwin::monitoringStop()
{
qDebug() << "Stop network monitoring";
dap_network_monitor_deinit();
m_isMonitoringRunning = false;
return true;
}
/**
* @brief SapNetworkMonitorDarwin::isOtherGatewayDefinedInnerCheck
* @return
*/
bool DapNetworkMonitorDarwin::isOtherGatewayDefinedInnerCheck() const
{
int ret;
if(m_tunnelGateway.size()>0){
ret = ::system(QString("netstat -nr |grep default | grep --invert-match '%1' > /dev/null").arg(m_tunnelGateway)
.toLatin1().constData());
if( ret!= 0){
qDebug() << "[-] No default gateway, checking direct route to upstream";
ret = ::system(QString("netstat -nr |grep '%1' | grep '%2' > /dev/null")
.arg(m_serverAddress).arg(m_defaultGateway)
.toLatin1().constData());
if(ret==0){
qDebug() << "[+] Direct route to "<< m_serverAddress <<" is present, checking if its actual";
ret = ::system(QString("netstat -nr | awk '{print $1;}' |egrep '%1'$ > /dev/null").arg(m_defaultGateway)
.toLatin1().constData());
if(ret==0){
qDebug() << "[+] Route to "<< m_defaultGateway <<" is present";
}else{
qDebug() << "[-] No route to "<< m_defaultGateway <<" in the routing table";
}
}else
qDebug() << "[-] No direct route to "<< m_serverAddress <<" in the routing table";
}
}else
ret = ::system(QString("netstat -nr |grep default > /dev/null").toLatin1().constData());
if(ret == 0 ){
qInfo() << "[+] Others gateway defined";
return true;
}else{
qInfo() << "[-] Others gateway undefined";
return false;
}
}
/**
* @brief SapNetworkMonitorDarwin::isTunGatewayDefinedInnerCheck
* @return
*/
bool DapNetworkMonitorDarwin::isTunGatewayDefinedInnerCheck() const
{
int ret;
if(m_tunnelGateway.size()>0)
ret = ::system(QString("netstat -nr |grep default | grep %1 > /dev/null ").arg(m_tunnelGateway)
.toLatin1().constData());
else
ret = ::system(QString("netstat -nr |grep default > /dev/null").toLatin1().constData());
if(ret == 0 ){
qInfo() << "[+] Tunnel gateway defined";
return true;
}else{
qInfo() << "[-] Tunnel gateway undefined";
return false;
}
}