diff --git a/lib/common.ts b/lib/common.ts index 955c9b8..e6b3018 100644 --- a/lib/common.ts +++ b/lib/common.ts @@ -1,6 +1,10 @@ import { Address4 } from './ipv4'; import { Address6 } from './ipv6'; +export interface ReverseFormOptions { + omitSuffix?: boolean; +} + export function isInSubnet(this: Address4 | Address6, address: Address4 | Address6) { if (this.subnetMask < address.subnetMask) { return false; diff --git a/lib/ipv4.ts b/lib/ipv4.ts index db69c1f..b6c61ff 100644 --- a/lib/ipv4.ts +++ b/lib/ipv4.ts @@ -117,6 +117,29 @@ export class Address4 { return Address4.fromHex(integer.toString(16)); } + + /** + * Return an address from in-addr.arpa form + * @memberof Address4 + * @static + * @param {string} arpaFormAddress - an 'in-addr.arpa' form ipv4 address + * @returns {Adress4} + * @example + * var address = Address4.fromArpa(42.2.0.192.in-addr.arpa.) + * address.correctForm(); // '192.0.2.42' + */ + static fromArpa(arpaFormAddress: string): Address4 { + // remove ending ".in-addr.arpa." or just "." + const leader = arpaFormAddress.replace(/(\.in-addr\.arpa)?\.$/, ''); + + const address = leader.split('.') + .reverse() + .join('.'); + + return new Address4(address); + } + + /** * Converts an IPv4 address object to a hex string * @memberof Address4 @@ -275,6 +298,31 @@ export class Address4 { return this.binaryZeroPad().slice(start, end); } + /** + * Return the reversed ip6.arpa form of the address + * @memberof Address4 + * @param {Object} options + * @param {boolean} options.omitSuffix - omit the "in-addr.arpa" suffix + * @instance + * @returns {String} + */ + reverseForm(options?: common.ReverseFormOptions): string { + if (!options) { + options = {}; + } + + const reversed = this.correctForm() + .split('.') + .reverse() + .join('.'); + + if (options.omitSuffix) { + return reversed; + } else { + return sprintf('%s.in-addr.arpa.', reversed); + } + } + /** * Returns true if the given address is in the subnet of the current address * @memberof Address4 diff --git a/lib/ipv6.ts b/lib/ipv6.ts index 70e14e8..2565d77 100644 --- a/lib/ipv6.ts +++ b/lib/ipv6.ts @@ -66,9 +66,6 @@ function unsignByte(b: number) { return b & 0xff; } -interface ReverseFormOptions { - omitSuffix?: boolean; -} interface SixToFourProperties { prefix: string; @@ -506,7 +503,7 @@ export class Address6 { * @instance * @returns {String} */ - reverseForm(options?: ReverseFormOptions): string { + reverseForm(options?: common.ReverseFormOptions): string { if (!options) { options = {}; } diff --git a/test/address-test.ts b/test/address-test.ts index 30d2aff..ac209d8 100644 --- a/test/address-test.ts +++ b/test/address-test.ts @@ -30,6 +30,14 @@ function addressIs(addressString: string, descriptors: string[]) { address4.subnetMask.should.be.at.least(0); address4.subnetMask.should.be.at.most(128); }); + it('converts to arpa format and back', () => { + const arpa = address4.reverseForm(); + arpa.length.should.be.at.most(29); + + const converted = Address4.fromArpa(arpa); + + address4.correctForm().should.equal(converted.correctForm()); + }); } if (descriptor === 'valid-ipv6') {