Skip to content

Commit 3ec229c

Browse files
Feature/ip cidr conversion (#103)
* Add CIDR notation support for IP addresses and subnets - Add UseCIDRNotation configuration option - Add Convert-AbrFgtSubnetToCIDR function for IP/subnet conversion - Implement CIDR conversion in firewall, route, system, and VPN IPsec sections - Add error handling and maintain backward compatibility * Add OutputType attributes to Convert-AbrFgtSubnetToCIDR functions * Add UseCIDRNotation option and convert CIDR notation checks to PowerShell 5.1 compatible one-liners
1 parent 5918d2e commit 3ec229c

File tree

7 files changed

+145
-31
lines changed

7 files changed

+145
-31
lines changed

AsBuiltReport.Fortinet.FortiGate.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,8 @@
1212
"Port": 443,
1313
"VDOM": "",
1414
"PolicyLayout": "all",
15-
"ExcludeDownInterfaces": true
15+
"ExcludeDownInterfaces": true,
16+
"UseCIDRNotation": false
1617
},
1718
"InfoLevel": {
1819
"_comment_": "0 = Disabled, 1 = Enabled / Summary, 2 = Adv Summary",

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,7 @@ The **Options** schema allows certain options within the report to be toggled on
127127
| VDOM | VDOM Name | | Used to specify the VDOM (Virtual Domain)
128128
| PolicyLayout | Policy Layout | all | Use to display Policy Layout (normal, interfacepair, sequencegroup, all)
129129
| ExcludeDownInterfaces | true / false | true | Toggle to exclude interfaces that are in down state from the report
130+
| UseCIDRNotation | true / false | false | Toggle to display IP addresses in CIDR notation format (e.g., 192.168.1.0/24 instead of 192.168.1.0 255.255.255.0)
130131

131132
<!-- ********** Add/Remove the number of InfoLevels as required ********** -->
132133
### InfoLevel
Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
function Convert-AbrFgtSubnetToCIDR {
2+
<#
3+
.SYNOPSIS
4+
Used by As Built Report to convert IP/Subnet to CIDR notation.
5+
.DESCRIPTION
6+
Converts IP addresses and subnet masks to CIDR notation format for Fortinet FortiGate As Built Report.
7+
.NOTES
8+
Version: 0.1.0
9+
Author: Alexis La Goutte
10+
Twitter: @alagoutte
11+
Github: alagoutte
12+
Credits: Iain Brighton (@iainbrighton) - PScribo module
13+
14+
.EXAMPLE
15+
Convert-AbrFgtSubnetToCIDR "192.168.1.0 255.255.255.0"
16+
Returns: 192.168.1.0/24
17+
18+
.EXAMPLE
19+
Convert-AbrFgtSubnetToCIDR "10.0.0.0/8"
20+
Returns: 10.0.0.0/8
21+
22+
.LINK
23+
https://github.com/AsBuiltReport/AsBuiltReport.Fortinet.FortiGate
24+
#>
25+
[CmdletBinding()]
26+
[OutputType([System.String])]
27+
param (
28+
[Parameter(Mandatory=$true, Position=0, ValueFromPipeline=$true)]
29+
[string]$Input
30+
)
31+
32+
process {
33+
$subnetMaskRegex = '^(0|128|192|224|240|248|252|254|255)\.0\.0\.0$|^(255\.(0|128|192|224|240|248|252|254|255)\.0\.0)$|^(255\.255\.(0|128|192|224|240|248|252|254|255)\.0)$|^(255\.255\.255\.(0|128|192|224|240|248|252|254|255))$'
34+
$ipAddressRegex = '^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$'
35+
36+
$parts = $Input -split '\s+'
37+
38+
if ($parts.Count -eq 2) {
39+
# IP address and subnet mask
40+
$ipAddress = $parts[0]
41+
$subnetMask = $parts[1]
42+
43+
if ($ipAddress -match $ipAddressRegex -and $subnetMask -match $subnetMaskRegex) {
44+
$cidr = Convert-AbrFgtSubnetMaskToCIDR -SubnetMask $subnetMask
45+
Write-PScriboMessage "Converted IP address $ipAddress and subnet mask $subnetMask to CIDR $ipAddress/$cidr."
46+
return "$ipAddress/$cidr"
47+
}
48+
} elseif ($parts.Count -eq 1) {
49+
if ($Input -match $subnetMaskRegex) {
50+
$cidr = Convert-AbrFgtSubnetMaskToCIDR -SubnetMask $Input
51+
Write-PScriboMessage "Converted subnet mask $Input to CIDR /$cidr."
52+
return "/$cidr"
53+
} elseif ($Input -match $ipAddressRegex) {
54+
Write-PScriboMessage "Input is a single IP address, assuming /32 CIDR."
55+
return "$Input/32"
56+
} elseif ($Input -match "^$ipAddressRegex/\d{1,2}$") {
57+
Write-PScriboMessage "Input is already in CIDR notation."
58+
return $Input
59+
}
60+
}
61+
62+
Write-Error "Invalid input format. Expected IP address with subnet mask, IP address, subnet mask, or IP address in CIDR notation."
63+
return $Input
64+
}
65+
}
66+
67+
function Convert-AbrFgtSubnetMaskToCIDR {
68+
<#
69+
.SYNOPSIS
70+
Used by As Built Report to convert subnet mask to CIDR prefix.
71+
.DESCRIPTION
72+
Converts subnet mask to CIDR prefix number for Fortinet FortiGate As Built Report.
73+
.NOTES
74+
Version: 0.1.0
75+
Author: Alexis La Goutte
76+
Twitter: @alagoutte
77+
Github: alagoutte
78+
Credits: Iain Brighton (@iainbrighton) - PScribo module
79+
80+
.EXAMPLE
81+
Convert-AbrFgtSubnetMaskToCIDR "255.255.255.0"
82+
Returns: 24
83+
84+
.EXAMPLE
85+
Convert-AbrFgtSubnetMaskToCIDR "255.255.0.0"
86+
Returns: 16
87+
88+
.EXAMPLE
89+
Convert-AbrFgtSubnetMaskToCIDR "255.255.255.252"
90+
Returns: 30
91+
92+
.LINK
93+
https://github.com/AsBuiltReport/AsBuiltReport.Fortinet.FortiGate
94+
#>
95+
[CmdletBinding()]
96+
[OutputType([System.String])]
97+
param (
98+
[Parameter(Mandatory=$true)]
99+
[string]$SubnetMask
100+
)
101+
102+
$cidr = [System.Net.IPAddress]::Parse($SubnetMask).GetAddressBytes() |
103+
ForEach-Object { [Convert]::ToString($_, 2).PadLeft(8, '0') } |
104+
ForEach-Object { $_.ToCharArray() } |
105+
Where-Object { $_ -eq '1' } |
106+
Measure-Object |
107+
Select-Object -ExpandProperty Count
108+
109+
if ($cidr -lt 0 -or $cidr -gt 32) {
110+
Write-Error "Invalid CIDR value. Expected a value between 0 and 32, but got $cidr."
111+
return $SubnetMask
112+
}
113+
114+
return $cidr
115+
}

Src/Private/Get-AbrFgtFirewall.ps1

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
21
function Get-AbrFgtFirewall {
32
<#
43
.SYNOPSIS
@@ -117,7 +116,7 @@ function Get-AbrFgtFirewall {
117116

118117
switch ( $add.type ) {
119118
"ipmask" {
120-
$value = $add.subnet.Replace(' ', '/')
119+
$value = $(if ($Options.UseCIDRNotation) { Convert-AbrFgtSubnetToCIDR -Input $add.subnet } else { $add.subnet.Replace(' ', '/') })
121120
}
122121
"iprange" {
123122
$value = $add.'start-ip' + "-" + $add.'end-ip'

Src/Private/Get-AbrFgtRoute.ps1

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
21
function Get-AbrFgtRoute {
32
<#
43
.SYNOPSIS
@@ -74,7 +73,7 @@ function Get-AbrFgtRoute {
7473

7574
$OutObj += [pscustomobject]@{
7675
"Type" = $route.type
77-
"IP/Mask" = $route.ip_mask
76+
"IP/Mask" = $(if ($Options.UseCIDRNotation) { Convert-AbrFgtSubnetToCIDR -Input $route.ip_mask } else { $route.ip_mask })
7877
"Gateway" = $route.gateway
7978
"Interface" = $interface
8079
"Distance/Metric/Priority" = "$($route.distance) / $($route.metric) / $($route.priority)"
@@ -110,7 +109,7 @@ function Get-AbrFgtRoute {
110109
#TODO: add Lookup, only display the id...
111110
$dst = $static.'internet-service'
112111
} else {
113-
$dst = $static.dst
112+
$dst = $(if ($Options.UseCIDRNotation) { Convert-AbrFgtSubnetToCIDR -Input $static.dst } else { $static.dst })
114113
}
115114

116115
#when Blackhole is enable, display blackhole for interface
@@ -153,13 +152,13 @@ function Get-AbrFgtRoute {
153152
foreach ($pbr in $PolicyBasedRouting) {
154153

155154
if ($pbr.src) {
156-
$src = $pbr.src.subnet
155+
$src = $(if ($Options.UseCIDRNotation) { Convert-AbrFgtSubnetToCIDR -Input $pbr.src.subnet } else { $pbr.src.subnet })
157156
}
158157
else {
159158
$src = $pbr.srcaddr.name
160159
}
161160
if ($pbr.dst) {
162-
$dst = $pbr.dst.subnet
161+
$dst = $(if ($Options.UseCIDRNotation) { Convert-AbrFgtSubnetToCIDR -Input $pbr.dst.subnet } else { $pbr.dst.subnet })
163162
}
164163
else {
165164
$dst = $pbr.dstaddr.name

Src/Private/Get-AbrFgtSystem.ps1

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -198,25 +198,25 @@ function Get-AbrFgtSystem {
198198
$Admins = Get-FGTSystemAdmin
199199

200200
if ($Admins -and $InfoLevel.System -ge 1) {
201-
Section -Style Heading3 'Admin' {
201+
Section -Style Heading3 'Administrators' {
202202
$OutObj = @()
203203

204204
foreach ($admin in $Admins) {
205205

206-
$trustedHosts = $admin.trusthost1 + "`n"
207-
$trustedHosts += $admin.trusthost2 + "`n"
208-
$trustedHosts += $admin.trusthost3 + "`n"
209-
$trustedHosts += $admin.trusthost4 + "`n"
210-
$trustedHosts += $admin.trusthost5 + "`n"
211-
$trustedHosts += $admin.trusthost6 + "`n"
212-
$trustedHosts += $admin.trusthost7 + "`n"
213-
$trustedHosts += $admin.trusthost8 + "`n"
214-
$trustedHosts += $admin.trusthost9 + "`n"
215-
$trustedHosts += $admin.trusthost10 + "`n"
216-
217-
$trustedHosts = $trustedHosts -replace "0.0.0.0 0.0.0.0`n", "" #Remove 'All Network'
218-
if ($trustedHosts -eq "") {
219-
$trustedHosts = "All" #TODO: Add Health Warning !
206+
$trustedHosts = @()
207+
for ($i = 1; $i -le 10; $i++) {
208+
$hostProperty = "trusthost$i"
209+
$hostValue = $admin.$hostProperty
210+
211+
if ($hostValue -and $hostValue -ne "0.0.0.0 0.0.0.0") {
212+
$trustedHosts += $(if ($Options.UseCIDRNotation) { Convert-AbrFgtSubnetToCIDR -Input $hostValue } else { $hostValue })
213+
}
214+
}
215+
216+
$trustedHostsString = if ($trustedHosts.Count -eq 0) {
217+
"All" #TODO: Add Health Warning !
218+
} else {
219+
$trustedHosts -join "`n"
220220
}
221221
$OutObj += [pscustomobject]@{
222222
"Name" = $admin.name
@@ -269,10 +269,10 @@ function Get-AbrFgtSystem {
269269
$interface.member = $interface.member.count -gt 0 ? $interface.member.'interface-name' -join ', ' : ""
270270
$interface.mtu = $interface.'mtu-override' -eq 'disable' ? '' : $interface.mtu
271271
$interface.mode = $interface.mode -eq 'static' ? '' : $interface.mode
272-
$interface.ip = $interface.ip -eq '0.0.0.0 0.0.0.0' ? '' : $interface.ip
272+
$interface.ip = $interface.ip -eq '0.0.0.0 0.0.0.0' ? '' : $(if ($Options.UseCIDRNotation) { Convert-AbrFgtSubnetToCIDR -Input $interface.ip } else { $interface.ip })
273273
$interface.'secondaryip' = if ($interface.'secondary-ip' -eq 'enable' -and $null -ne $interface.'secondaryip') {
274274
($interface.'secondaryip' | ForEach-Object {
275-
$_.ip
275+
$(if ($Options.UseCIDRNotation) { Convert-AbrFgtSubnetToCIDR -Input $_.ip } else { $_.ip })
276276
}) -join ', '
277277
} else {
278278
""
@@ -281,7 +281,7 @@ function Get-AbrFgtSystem {
281281
$interface.vdom = $interface.vdom -eq 'root' ? '' : $interface.vdom
282282
$interface.vlanid = ($interface.vlanid -gt 0 ) ? $interface.vlanid : ""
283283
$interface.speed = $interface.speed -eq 'auto' ? '' : $interface.speed
284-
$interface.'remote-ip' = $interface.'remote-ip' -eq '0.0.0.0 0.0.0.0' ? '' : $interface.'remote-ip'
284+
$interface.'remote-ip' = $interface.'remote-ip' -eq '0.0.0.0 0.0.0.0' ? '' : $(if ($Options.UseCIDRNotation) { Convert-AbrFgtSubnetToCIDR -Input $interface.'remote-ip' } else { $interface.'remote-ip' })
285285

286286

287287
switch ($interfaceType) {

Src/Private/Get-AbrFgtVPNIPsec.ps1

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
21
function Get-AbrFgtVPNIPsec {
32
<#
43
.SYNOPSIS
@@ -146,7 +145,7 @@ function Get-AbrFgtVPNIPsec {
146145
$src = $v2.'src-name'
147146
}
148147
"subnet" {
149-
$src = $v2.'src-subnet' -replace " ", "/"
148+
$src = $(if ($Options.UseCIDRNotation) { Convert-AbrFgtSubnetToCIDR -Input $v2.'src-subnet' } else { $v2.'src-subnet' -replace " ", "/" })
150149
}
151150
Default {}
152151
}
@@ -155,7 +154,7 @@ function Get-AbrFgtVPNIPsec {
155154
$dst = $v2.'dst-name'
156155
}
157156
"subnet" {
158-
$dst = $v2.'dst-subnet' -replace " ", "/"
157+
$dst = $(if ($Options.UseCIDRNotation) { Convert-AbrFgtSubnetToCIDR -Input $v2.'dst-subnet' } else { $v2.'dst-subnet' -replace " ", "/" })
159158
}
160159
Default {}
161160
}
@@ -202,10 +201,10 @@ function Get-AbrFgtVPNIPsec {
202201
"Keylife Kbs" = $v2.keylifekbs
203202
'Source Address Type' = $v2.'src-addr-type'
204203
'Source Address Name' = $v2.'src-name'
205-
'Source Address Subnet' = $v2.'src-subnet'
204+
'Source Address Subnet' = $(if ($Options.UseCIDRNotation) { Convert-AbrFgtSubnetToCIDR -Input $v2.'src-subnet' } else { $v2.'src-subnet' })
206205
'Destination Address Type' = $v2.'dst-addr-type'
207206
'Destination Address Name' = $v2.'dst-name'
208-
'Destination Address Subnet' = $v2.'dst-subnet'
207+
'Destination Address Subnet' = $(if ($Options.UseCIDRNotation) { Convert-AbrFgtSubnetToCIDR -Input $v2.'dst-subnet' } else { $v2.'dst-subnet' })
209208
}
210209

211210

0 commit comments

Comments
 (0)