|
14 | 14 | * Generates visual representation of network range |
15 | 15 | */ |
16 | 16 | function generateNetworkBlocks() { |
17 | | - const totalHosts = subnetInfo.hostCount; |
18 | | - const _usableHosts = subnetInfo.usableHosts; |
19 | | - const cidr = subnetInfo.cidr; |
20 | | -
|
21 | | - // For visualization, we'll show up to 256 blocks max |
| 17 | + const { hostCount, cidr } = subnetInfo; |
22 | 18 | const maxBlocks = 256; |
23 | | - const blocksToShow = Math.min(totalHosts, maxBlocks); |
24 | | - const blockSize = totalHosts > maxBlocks ? Math.ceil(totalHosts / maxBlocks) : 1; |
25 | | -
|
26 | | - const blocks = []; |
27 | | -
|
28 | | - // RFC 3021: /31 networks have no network/broadcast addresses |
29 | | - const is31Subnet = cidr === 31; |
30 | | - const is32Subnet = cidr === 32; |
31 | | -
|
32 | | - for (let i = 0; i < blocksToShow; i++) { |
33 | | - let type: 'network' | 'broadcast' | 'usable'; |
34 | | - let tooltip: string; |
35 | | -
|
36 | | - if (is31Subnet) { |
37 | | - // /31: Both IPs are usable hosts (point-to-point) |
38 | | - type = 'usable'; |
39 | | - tooltip = i === 0 ? 'Usable Host 1 (P2P)' : 'Usable Host 2 (P2P)'; |
40 | | - } else if (is32Subnet) { |
41 | | - // /32: Single host |
42 | | - type = 'usable'; |
43 | | - tooltip = 'Single Host'; |
44 | | - } else { |
45 | | - // Normal subnet: first is network, last is broadcast, rest are usable |
46 | | - const isNetwork = i === 0; |
47 | | - const isBroadcast = i === blocksToShow - 1 && totalHosts > 2; |
48 | | -
|
49 | | - type = isNetwork ? 'network' : isBroadcast ? 'broadcast' : 'usable'; |
50 | | - tooltip = isNetwork |
51 | | - ? 'Network Address' |
52 | | - : isBroadcast |
53 | | - ? 'Broadcast Address' |
54 | | - : `Usable Host${blockSize > 1 ? 's' : ''}`; |
| 19 | + const blocksToShow = Math.min(hostCount, maxBlocks); |
| 20 | + const blockSize = hostCount > maxBlocks ? Math.ceil(hostCount / maxBlocks) : 1; |
| 21 | +
|
| 22 | + return Array.from({ length: blocksToShow }, (_, i) => { |
| 23 | + const isFirst = i === 0; |
| 24 | + const isLast = i === blocksToShow - 1; |
| 25 | +
|
| 26 | + // RFC 3021: /31 and /32 have all IPs usable |
| 27 | + if (cidr === 31) { |
| 28 | + return { |
| 29 | + id: i, |
| 30 | + type: 'usable' as const, |
| 31 | + represents: blockSize, |
| 32 | + tooltip: isFirst ? 'Usable Host 1 (P2P)' : 'Usable Host 2 (P2P)', |
| 33 | + }; |
55 | 34 | } |
56 | 35 |
|
57 | | - blocks.push({ |
58 | | - id: i, |
59 | | - type, |
60 | | - represents: blockSize, |
61 | | - tooltip, |
62 | | - }); |
63 | | - } |
| 36 | + if (cidr === 32) { |
| 37 | + return { |
| 38 | + id: i, |
| 39 | + type: 'usable' as const, |
| 40 | + represents: blockSize, |
| 41 | + tooltip: 'Single Host', |
| 42 | + }; |
| 43 | + } |
| 44 | +
|
| 45 | + // Normal subnets have network/broadcast reserved |
| 46 | + const type = isFirst ? 'network' : isLast && hostCount > 2 ? 'broadcast' : 'usable'; |
| 47 | + const tooltip = isFirst |
| 48 | + ? 'Network Address' |
| 49 | + : isLast && hostCount > 2 |
| 50 | + ? 'Broadcast Address' |
| 51 | + : `Usable Host${blockSize > 1 ? 's' : ''}`; |
64 | 52 |
|
65 | | - return blocks; |
| 53 | + return { id: i, type, represents: blockSize, tooltip }; |
| 54 | + }); |
66 | 55 | } |
67 | 56 |
|
68 | 57 | let networkBlocks = $derived(generateNetworkBlocks()); |
|
0 commit comments