2024-04-04 15:54:43 +01:00
/**
* @author jb30795 [jb30795@proton.me]
* @copyright Crown Copyright 2024
* @license Apache-2.0
*/
import Operation from "../Operation.mjs" ;
/**
* IPv6 Transition Addresses operation
*/
class IPv6TransitionAddresses extends Operation {
/**
* IPv6TransitionAddresses constructor
*/
constructor () {
super ();
this . name = "IPv6 Transition Addresses" ;
this . module = "Default" ;
this . description = "Converts IPv4 addresses to their IPv6 Transition addresses. IPv6 Transition addresses can also be converted back into their original IPv4 address. MAC addresses can also be converted into the EUI-64 format, this can them be appended to your IPv6 /64 range to obtain a full /128 address.<br><br>Transition technologies enable translation between IPv4 and IPv6 addresses or tunneling to allow traffic to pass through the incompatible network, allowing the two standards to coexist." ;
this . infoURL = "https://wikipedia.org/wiki/IPv6_transition_mechanism" ;
this . inputType = "string" ;
this . outputType = "string" ;
2024-08-07 17:06:15 +01:00
this . args = [
{
"name" : "Ignore ranges" ,
"type" : "boolean" ,
"value" : true
2024-08-07 18:17:00 +01:00
},
{
"name" : "Remove headers" ,
"type" : "boolean" ,
"value" : false
}
2024-08-07 17:06:15 +01:00
];
2024-04-04 15:54:43 +01:00
}
2024-08-07 17:06:15 +01:00
/**
2024-04-04 15:54:43 +01:00
* @param {string} input
* @param {Object[]} args
* @returns {string}
*/
run ( input , args ) {
const XOR = { "0" : "2" , "1" : "3" , "2" : "0" , "3" : "1" , "4" : "6" , "5" : "7" , "6" : "4" , "7" : "5" , "8" : "A" , "9" : "B" , "A" : "8" , "B" : "9" , "C" : "E" , "D" : "F" , "E" : "C" , "F" : "D" };
2024-08-07 18:17:00 +01:00
const [ ignoreRanges , removeHeaders ] = args ;
2024-04-04 15:54:43 +01:00
/**
* Function to convert to hex
*/
function hexify ( octet ) {
return Number ( octet ). toString ( 16 ). padStart ( 2 , "0" );
}
/**
* Function to convert Hex to Int
*/
function intify ( hex ) {
return parseInt ( hex , 16 );
}
/**
* Function converts IPv4 to IPv6 Transtion address
*/
function ipTransition ( input ) {
let output = "" ;
const HEXIP = input . split ( "." );
/**
* 6to4
*/
2024-08-07 18:17:00 +01:00
if ( ! args [ 1 ]){
output += "6to4: " ;
}
output += "2002:" + hexify ( HEXIP [ 0 ]) + hexify ( HEXIP [ 1 ]) + ":" + hexify ( HEXIP [ 2 ]) + hexify ( HEXIP [ 3 ]) + "::/48\n" ;
2024-04-04 15:54:43 +01:00
/**
* Mapped
*/
2024-08-07 18:17:00 +01:00
if ( ! args [ 1 ]){
output += "IPv4 Mapped: " ;
}
output += "::ffff:" + hexify ( HEXIP [ 0 ]) + hexify ( HEXIP [ 1 ]) + ":" + hexify ( HEXIP [ 2 ]) + hexify ( HEXIP [ 3 ]) + "\n" ;
2024-04-04 15:54:43 +01:00
/**
* Translated
*/
2024-08-07 18:17:00 +01:00
if ( ! args [ 1 ]){
output += "IPv4 Translated: " ;
}
output += "::ffff:0:" + hexify ( HEXIP [ 0 ]) + hexify ( HEXIP [ 1 ]) + ":" + hexify ( HEXIP [ 2 ]) + hexify ( HEXIP [ 3 ]) + "\n" ;
2024-04-04 15:54:43 +01:00
/**
* Nat64
*/
2024-08-07 18:17:00 +01:00
if ( ! args [ 1 ]){
output += "Nat 64: " ;
}
output += "64:ff9b::" + hexify ( HEXIP [ 0 ]) + hexify ( HEXIP [ 1 ]) + ":" + hexify ( HEXIP [ 2 ]) + hexify ( HEXIP [ 3 ]) + "\n" ;
2024-04-04 15:54:43 +01:00
return output ;
}
/**
* Convert MAC to EUI-64
*/
function macTransition ( input ) {
let output = "" ;
const MACPARTS = input . split ( ":" );
2024-08-07 18:17:00 +01:00
if ( ! args [ 1 ]){
output += "EUI-64 Interface ID: " ;
}
2024-04-04 15:54:43 +01:00
const MAC = MACPARTS [ 0 ] + MACPARTS [ 1 ] + ":" + MACPARTS [ 2 ] + "ff:fe" + MACPARTS [ 3 ] + ":" + MACPARTS [ 4 ] + MACPARTS [ 5 ];
output += MAC . slice ( 0 , 1 ) + XOR [ MAC . slice ( 1 , 2 ). toUpperCase ()]. toLowerCase () + MAC . slice ( 2 );
return output ;
}
/**
* Convert IPv6 address to its original IPv4 or MAC address
*/
function unTransition ( input ) {
let output = "" ;
let hextets = "" ;
/**
* 6to4
*/
if ( input . startsWith ( "2002:" )) {
2024-08-07 18:17:00 +01:00
if ( ! args [ 1 ]){
output += "IPv4: " ;
}
output += String ( intify ( input . slice ( 5 , 7 ))) + "." + String ( intify ( input . slice ( 7 , 9 ))) + "." + String ( intify ( input . slice ( 10 , 12 ))) + "." + String ( intify ( input . slice ( 12 , 14 ))) + "\n" ;
2024-04-04 15:54:43 +01:00
} else if ( input . startsWith ( "::ffff:" ) || input . startsWith ( "0000:0000:0000:0000:0000:ffff:" ) || input . startsWith ( "::ffff:0000:" ) || input . startsWith ( "0000:0000:0000:0000:ffff:0000:" ) || input . startsWith ( "64:ff9b::" ) || input . startsWith ( "0064:ff9b:0000:0000:0000:0000:" )) {
/**
* Mapped/Translated/Nat64
*/
hextets = /:([0-9a-z]{1,4}):[0-9a-z]{1,4}$/ . exec ( input )[ 1 ]. padStart ( 4 , "0" ) + /:([0-9a-z]{1,4})$/ . exec ( input )[ 1 ]. padStart ( 4 , "0" );
2024-08-07 18:17:00 +01:00
if ( ! args [ 1 ]){
output += "IPv4: " ;
}
output += intify ( hextets . slice ( - 8 , - 7 ) + hextets . slice ( - 7 , - 6 )) + "." + intify ( hextets . slice ( - 6 , - 5 ) + hextets . slice ( - 5 , - 4 )) + "." + intify ( hextets . slice ( - 4 , - 3 ) + hextets . slice ( - 3 , - 2 )) + "." + intify ( hextets . slice ( - 2 , - 1 ) + hextets . slice ( - 1 ,)) + "\n" ;
2024-04-04 15:54:43 +01:00
} else if ( input . slice ( - 12 , - 7 ). toUpperCase () === "FF:FE" ) {
/**
* EUI-64
*/
2024-08-07 18:17:00 +01:00
if ( ! args [ 1 ]){
output += "Mac Address: " ;
}
2024-04-04 15:54:43 +01:00
const MAC = ( input . slice ( - 19 , - 17 ) + ":" + input . slice ( - 17 , - 15 ) + ":" + input . slice ( - 14 , - 12 ) + ":" + input . slice ( - 7 , - 5 ) + ":" + input . slice ( - 4 , - 2 ) + ":" + input . slice ( - 2 ,)). toUpperCase ();
2024-08-07 18:17:00 +01:00
output += MAC . slice ( 0 , 1 ) + XOR [ MAC . slice ( 1 , 2 )] + MAC . slice ( 2 ) + "\n" ;
2024-04-04 15:54:43 +01:00
}
return output ;
}
/**
* Main
*/
let output = "" ;
2024-08-07 18:17:00 +01:00
let inputs = input . split ( "\n" );
//Remove blank rows
inputs = inputs . filter ( Boolean );
2024-08-07 17:06:15 +01:00
for ( let input = 0 ; input < inputs . length ; input ++ ){
if ( /^[0-9]{1,3}(?:\.[0-9]{1,3}){3}$/ . test ( inputs [ input ])) {
output += ipTransition ( inputs [ input ]);
} else if ( /^([0-9A-F]{2}:){5}[0-9A-F]{2}$/ . test ( inputs [ input ]. toUpperCase ())) {
output += macTransition ( input . toLowerCase ());
} else if ( /^((?:[0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|(?:[0-9a-fA-F]{1,4}:){1,7}:|(?:[0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|(?:[0-9a-fA-F]{1,4}:){1,5}(?::[0-9a-fA-F]{1,4}){1,2}|(?:[0-9a-fA-F]{1,4}:){1,4}(?::[0-9a-fA-F]{1,4}){1,3}|(?:[0-9a-fA-F]{1,4}:){1,3}(?::[0-9a-fA-F]{1,4}){1,4}|(?:[0-9a-fA-F]{1,4}:){1,2}(?::[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:(?:(?::[0-9a-fA-F]{1,4}){1,6})|:(?:(?::[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(?::[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(?:ffff(?::0{1,4}){0,1}:){0,1}(?:(?:25[0-5]|(?:2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(?:25[0-5]|(?:2[0-4]|1{0,1}[0-9]){0,1}[0-9])|(?:[0-9a-fA-F]{1,4}:){1,4}:(?:(?:25[0-5]|(?:2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(?:25[0-5]|(?:2[0-4]|1{0,1}[0-9]){0,1}[0-9]))$/ . test ( inputs [ input ])) {
output += unTransition ( inputs [ input ]);
} else {
output = "Enter a compressed or expanded IPv6 address, IPv4 address or MAC Address." ;
}
2024-04-04 15:54:43 +01:00
}
return output ;
}
}
export default IPv6TransitionAddresses ;