UNPKG

5.61 kBJavaScriptView Raw
1import IP from "./IP.js"
2import binary from './binary.js'
3
4String.prototype.replaceAt = function(index, replacement) {
5 return this.substr(0, index) + replacement + this.substr(index + replacement.length);
6}
7
8export default class Subnet {
9 #networkAddress
10 #suffix
11
12 constructor(networkAddress, suffix) {
13 if (typeof networkAddress === 'undefined') {
14 throw new Error('Incorrect arguments for Subnet. Expected (IP, number)')
15 }
16 if (typeof suffix === 'undefined') {
17 throw new Error('Incorrect arguments for Subnet. Expected (IP, number)')
18 }
19
20 const correctNetworkAddress = Subnet.calcNetworkAddress(networkAddress, suffix).asDecimalArray()
21 let wrongNetworkAddress = false
22 for (let i = 0; i < networkAddress.asDecimalArray().length; i++) {
23 if (networkAddress.asDecimalArray()[i] !== correctNetworkAddress[i]) wrongNetworkAddress = true
24 }
25
26 if (wrongNetworkAddress) {
27 throw new Error(`Wrong network address for given suffix.
28 Expected: ${checkNetworkAddress.toString()} got: ${decimalArgumentIP.toString()}`)
29 }
30
31 this.#networkAddress = networkAddress
32 this.#suffix = suffix
33 }
34
35 #getBinaryNetworkMask = () => {
36 let networkMask = ''
37 for (let i = 0; i < this.#suffix; i++) {
38 networkMask += '1'
39 }
40 for (let j = 0; j < 32 - this.#suffix; j++) {
41 networkMask += '0'
42 }
43 return binary.splitIntoOctets(networkMask)
44 }
45
46 getDecimalNetworkMask = () => {
47 const binaryAddress = this.#getBinaryNetworkMask()
48 let networkMask = []
49
50 for (let i = 0; i < binaryAddress.length; i++) {
51 networkMask.push(binary.octetToDecimal(binaryAddress[i]))
52 }
53
54 return networkMask
55 }
56
57 broadcast = () => {
58 let hostBits = ''
59 for (let i = 0; i < 32 - this.#suffix; i++) {
60 hostBits += '1'
61 }
62
63 const broadcastBinaryString = this.#networkBitsToBinaryString() + hostBits
64 const broadcastOctetArray = binary.splitIntoOctets(broadcastBinaryString)
65
66 return IP.fromBinaryOctetArray(broadcastOctetArray)
67 }
68
69 #findPermutations = (bits) => {
70 if (!bits || typeof bits !== "string"){
71 throw new Error(`Invalid argument. expected (String)`)
72 } else if (bits.length < 2 ){
73 return bits
74 }
75
76 let permutationsArray = []
77
78 for (let i = 0; i < bits.length; i++){
79 let bit = bits[i]
80
81 if (bits.indexOf(bit) != i)
82 continue
83
84 let remainingBits = bits.slice(0, i) + bits.slice(i + 1, bits.length)
85
86 for (let permutation of this.#findPermutations(remainingBits)){
87 permutationsArray.push(bit + permutation)
88 }
89 }
90 return permutationsArray
91 }
92
93 #networkBitsToBinaryString = () => {
94 let networkBits = ''
95
96 for (let octet of this.#networkAddress.asBinaryArray()) {
97 networkBits += octet
98 }
99 networkBits = networkBits.slice(0, this.#suffix)
100
101 return networkBits
102 }
103
104 #hostBitPermutations = () => {
105 let hostBits = ''
106 for (let i = 0; i < 32 - this.#suffix; i++) {
107 hostBits += '0'
108 }
109
110 let permutations = []
111
112 for (let j = 0; j < hostBits.length - 1; j++) {
113 hostBits = hostBits.replaceAt(j, '1')
114 for (let permutation of this.#findPermutations(hostBits)) {
115 permutations.push(permutation)
116 }
117 }
118
119 permutations.sort()
120 return permutations
121 }
122
123 getHostAddresses = () => {
124 let hostAddresses = []
125
126 if (this.#suffix < 16)
127 throw new Error('This method is disabled for subnets with less then 16 networkbits! (For js performance reasons)')
128
129 for (let hostBits of this.#hostBitPermutations()) {
130 const hostAddressBinaryString = this.#networkBitsToBinaryString() + hostBits
131 const hostAddressOctetArray = binary.splitIntoOctets(hostAddressBinaryString)
132
133 hostAddresses.push(IP.fromBinaryOctetArray(hostAddressOctetArray))
134 }
135
136 return hostAddresses
137 }
138
139 static calcNetworkAddress = (address, suffix) => {
140 let networkMask = ''
141 for (let i = 0; i < suffix; i++) {
142 networkMask += '1'
143 }
144 for (let j = 0; j < 32 - suffix; j++) {
145 networkMask += '0'
146 }
147
148 const binaryAddress = binary.splitIntoOctets(networkMask)
149 let decimalNetworkMask = []
150 for (let i = 0; i < binaryAddress.length; i++) {
151 decimalNetworkMask.push(binary.octetToDecimal(binaryAddress[i]))
152 }
153
154 const decimalAddress = address.asDecimalArray()
155 let na = []
156 for (let i = 0; i < decimalAddress.length; i++) {
157 na.push(binary.logicalAnd(decimalAddress[i], decimalNetworkMask[i]))
158 }
159
160 return new IP(`${na[0]}.${na[1]}.${na[2]}.${na[3]}`)
161 }
162
163 possibleHostCount = () => {
164 return (2 ** (32 - this.#suffix)) - 2
165 }
166
167 toString = () => {
168 return `${this.#networkAddress} /${this.#suffix}`
169 }
170
171 get networkAddress() {
172 return this.#networkAddress
173 }
174
175 get suffix() {
176 return this.#suffix
177 }
178}
\No newline at end of file