Skip to content

Commit 90a8fab

Browse files
committed
Merge branch 'bugfix/interface_detection'
2 parents 3e86748 + 9b6941c commit 90a8fab

File tree

3 files changed

+123
-69
lines changed

3 files changed

+123
-69
lines changed

lib/core/tools/ConvertTo-IcingaIPBinaryString.psm1

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -21,16 +21,17 @@
2121

2222
function ConvertTo-IcingaIPBinaryString()
2323
{
24-
param(
25-
$IP
26-
);
27-
if ($IP -like '*.*') {
28-
$IP = ConvertTo-IcingaIPv4BinaryString -IP $IP;
29-
} elseif ($IP -like '*:*') {
30-
$IP = ConvertTo-IcingaIPv6BinaryString -IP $IP;
31-
} else {
32-
return 'Invalid IP was provided!';
33-
}
24+
param(
25+
$IP
26+
);
3427

35-
return $IP;
36-
}
28+
if ($IP -like '*.*') {
29+
$IP = ConvertTo-IcingaIPv4BinaryString -IP $IP;
30+
} elseif ($IP -like '*:*') {
31+
$IP = ConvertTo-IcingaIPv6BinaryString -IP $IP;
32+
} else {
33+
return 'Invalid IP was provided!';
34+
}
35+
36+
return $IP;
37+
}

lib/core/tools/ConvertTo-IcingaIPv4BinaryString.psm1

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -21,18 +21,24 @@
2121

2222
function ConvertTo-IcingaIPv4BinaryString()
2323
{
24-
param(
25-
[string]$IP
26-
);
24+
param(
25+
[string]$IP
26+
);
2727

28-
$IP = $IP -split '\.' | ForEach-Object {
29-
[System.Convert]::ToString($_, 2).PadLeft(8, '0');
30-
}
31-
$IP = $IP -join '';
32-
$IP = $IP -replace '\s','';
33-
34-
return @{
35-
'value' = $IP;
36-
'name' = 'IPv4'
28+
try {
29+
$IP = $IP -split '\.' | ForEach-Object {
30+
[System.Convert]::ToString($_, 2).PadLeft(8, '0');
31+
}
32+
$IP = $IP -join '';
33+
$IP = $IP -replace '\s','';
34+
} catch {
35+
# Todo: Should we handle errors? It might happen due to faulty routes or unhandled route config
36+
# we throw errors which should have no effect at all
37+
return $null;
38+
}
39+
40+
return @{
41+
'value' = $IP;
42+
'name' = 'IPv4'
3743
}
3844
}

lib/core/tools/Get-IcingaNetworkInterface.psm1

Lines changed: 92 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ function Get-IcingaNetworkInterface()
3737
}
3838

3939
try {
40-
$IP = ([System.Net.Dns]::GetHostAddresses($IP)).IPAddressToString;
40+
[array]$IP = ([System.Net.Dns]::GetHostAddresses($IP)).IPAddressToString;
4141
} catch {
4242
Write-Host 'Invalid IP was provided!';
4343
return $null;
@@ -53,72 +53,119 @@ function Get-IcingaNetworkInterface()
5353
foreach ( $Info in $InterfaceInfo ) {
5454
$Counter++;
5555

56-
$Divide = $Info.DestinationPrefix;
57-
$IP,$Mask = $Divide.Split('/');
56+
$Divide = $Info.DestinationPrefix;
57+
$IP, $Mask = $Divide.Split('/');
5858

59+
foreach ($destinationIP in $IPBinStringMaster) {
60+
[string]$Key = '';
61+
[string]$MaskKey = '';
5962
############################################################################
6063
################################ IPv4 ####################################
6164
############################################################################
62-
if ($IPBinStringMaster.name -eq 'IPv4') {
63-
if ($IP -like '*.*') {
65+
if ($destinationIP.name -eq 'IPv4') {
66+
if ($IP -like '*.*') {
6467
############################################################################
65-
if ([int]$Mask -lt 10) {
66-
[string]$MaskKey = [string]::Format('00{0}', $Mask);
67-
} else {
68-
[string]$MaskKey = [string]::Format('0{0}', $Mask);
69-
}
70-
71-
[string]$Key = [string]::Format('{0}-{1}', $MaskKey, $Counter);
72-
73-
$InterfaceData.Add(
74-
$Key, @{
75-
'Binary IP String' = (ConvertTo-IcingaIPBinaryString -IP $IP).value;
76-
'Mask' = $Mask;
77-
'Interface' = $Info.ifIndex;
68+
if ([int]$Mask -lt 10) {
69+
$MaskKey = [string]::Format('00{0}', $Mask);
70+
} else {
71+
$MaskKey = [string]::Format('0{0}', $Mask);
7872
}
79-
);
8073
############################################################################
74+
}
8175
}
82-
}
8376
############################################################################
84-
################################ IPv4 ####################################
77+
################################ IPv6 ####################################
8578
############################################################################
86-
if ($IPBinStringMaster.name -eq 'IPv6') {
87-
if ($IP -like '*:*') {
79+
if ($destinationIP.name -eq 'IPv6') {
80+
if ($IP -like '*:*') {
81+
############################################################################
82+
if ([int]$Mask -lt 10) {
83+
$MaskKey = [string]::Format('00{0}', $Mask);
84+
} elseif ([int]$Mask -lt 100) {
85+
$MaskKey = [string]::Format('0{0}', $Mask);
86+
} else {
87+
$MaskKey = $Mask;
88+
}
8889
############################################################################
89-
if ([int]$Mask -lt 10) {
90-
[string]$MaskKey = [string]::Format('00{0}', $Mask);
91-
} elseif ([int]$Mask -lt 100) {
92-
[string]$MaskKey = [string]::Format('0{0}', $Mask);
93-
} else {
94-
[string]$MaskKey = $Mask;
9590
}
91+
}
9692

97-
[string]$Key = [string]::Format('{0}-{1}', $MaskKey, $Counter);
93+
$Key = [string]::Format('{0}-{1}', $MaskKey, $Counter);
9894

99-
$InterfaceData.Add(
100-
$Key, @{
101-
'Binary IP String' = (ConvertTo-IcingaIPBinaryString -IP $IP);
102-
'Mask' = $Mask;
103-
'Interface' = $Info.ifIndex;
104-
}
105-
);
106-
############################################################################
95+
if ($InterfaceData.ContainsKey($Key)) {
96+
continue;
10797
}
98+
99+
$InterfaceData.Add(
100+
$Key, @{
101+
'Binary IP String' = (ConvertTo-IcingaIPBinaryString -IP $IP).value;
102+
'Mask' = $Mask;
103+
'Interface' = $Info.ifIndex;
104+
}
105+
);
108106
}
109107
}
110108

111109
$InterfaceDataOrdered = $InterfaceData.GetEnumerator() | Sort-Object -Property Name -Descending;
110+
$ExternalInterfaces = @{};
112111

113112
foreach ( $Route in $InterfaceDataOrdered ) {
114-
[string]$RegexPattern = [string]::Format("^.{{{0}}}", $Route.Value.Mask);
115-
[string]$ToBeMatched = $Route.Value."Binary IP String";
116-
$Match1=[regex]::Matches($ToBeMatched, $RegexPattern).Value;
117-
$Match2=[regex]::Matches($IPBinStringMaster.Value, $RegexPattern).Value;
113+
foreach ($destinationIP in $IPBinStringMaster) {
114+
[string]$RegexPattern = [string]::Format("^.{{{0}}}", $Route.Value.Mask);
115+
[string]$ToBeMatched = $Route.Value."Binary IP String";
116+
if ($null -eq $ToBeMatched) {
117+
continue;
118+
}
119+
120+
$Match1=[regex]::Matches($ToBeMatched, $RegexPattern).Value;
121+
$Match2=[regex]::Matches($destinationIP.Value, $RegexPattern).Value;
122+
123+
If ($Match1 -like $Match2) {
124+
$ExternalInterface = ((Get-NetIPAddress -InterfaceIndex $Route.Value.Interface -AddressFamily $destinationIP.Name -ErrorAction SilentlyContinue).IPAddress);
125+
126+
# If no interface was found -> skip this entry
127+
if ($null -eq $ExternalInterface) {
128+
continue;
129+
}
130+
131+
if ($ExternalInterfaces.ContainsKey($ExternalInterface)) {
132+
$ExternalInterfaces[$ExternalInterface].count += 1;
133+
} else {
134+
$ExternalInterfaces.Add(
135+
$ExternalInterface,
136+
@{
137+
'count' = 1
138+
}
139+
);
140+
}
141+
}
142+
}
143+
}
144+
145+
if ($ExternalInterfaces.Count -eq 0) {
146+
foreach ($destinationIP in $IPBinStringMaster) {
147+
$ExternalInterface = ((Get-NetIPAddress -InterfaceIndex (Get-NetRoute | Where-Object -Property DestinationPrefix -like '0.0.0.0/0')[0].IfIndex -AddressFamily $destinationIP.name).IPAddress).split('%')[0];
148+
if ($ExternalInterfaces.ContainsKey($ExternalInterface)) {
149+
$ExternalInterfaces[$ExternalInterface].count += 1;
150+
} else {
151+
$ExternalInterfaces.Add(
152+
$ExternalInterface,
153+
@{
154+
'count' = 1
155+
}
156+
);
157+
}
158+
}
159+
}
118160

119-
If ($Match1 -like $Match2) {
120-
return ((Get-NetIPAddress -InterfaceIndex $Route.Value.Interface -AddressFamily $IPBinStringMaster.name).IPAddress);
161+
$InternalCount = 0;
162+
$UseInterface = '';
163+
foreach ($interface in $ExternalInterfaces.Keys) {
164+
$currentCount = $ExternalInterfaces[$interface].count;
165+
if ($currentCount -gt $InternalCount) {
166+
$InternalCount = $currentCount;
167+
$UseInterface = $interface;
121168
}
122169
}
123-
return ((Get-NetIPAddress -InterfaceIndex (Get-NetRoute | Where-Object -Property DestinationPrefix -like '0.0.0.0/0')[0].IfIndex -AddressFamily $IPBinStringMaster.name).IPAddress).split('%')[0];
170+
return $UseInterface;
124171
}

0 commit comments

Comments
 (0)