diff --git a/index.js b/index.js new file mode 100644 index 0000000..04894ac --- /dev/null +++ b/index.js @@ -0,0 +1,180 @@ +function hex2dec(val){ + return parseInt("0x"+val); +} + +function dec2hex(val){ + var str=""; + var minus=false; + if(val<0){minus=true;val*=-1;} + val=Math.floor(val); + while(val>0){ + var v=val%16; + val/=16;val=Math.floor(val); + switch(v){ + case 10:v="a";break; + case 11:v="b";break; + case 12:v="c";break; + case 13:v="d";break; + case 14:v="e";break; + case 15:v="f";break; + } + str=v + str; + } + if(str=="")str="0"; + if(minus)str="-"+str; + return str; +} + +function dec2hexlen(val,minlen){ + var str=dec2hex(val); + while(str.length8)slen=8; + var j=0; + for(var i=0;i2 && zl>zlf){zlf=zl;zsf=zs;} + } + for(var i=0;i<8;i++){ + if(i==zsf){ + str+=":"; + i+=zlf-1; + if(i>=7)str+=":"; + continue; + } + if(i)str+=":"; + str+=dec2hex(ar[i]); + } + return str; +} +function ip6prefixToMask(prf){ + var ar=new Array; + for(var i=0;i<8;i++){ + if(prf>=16)ar[i]=0xffff; + else switch(prf){ + case 1:ar[i]=0x8000;break; + case 2:ar[i]=0xc000;break; + case 3:ar[i]=0xe000;break; + case 4:ar[i]=0xf000;break; + case 5:ar[i]=0xf800;break; + case 6:ar[i]=0xfc00;break; + case 7:ar[i]=0xfe00;break; + case 8:ar[i]=0xff00;break; + case 9:ar[i]=0xff80;break; + case 10:ar[i]=0xffc0;break; + case 11:ar[i]=0xffe0;break; + case 12:ar[i]=0xfff0;break; + case 13:ar[i]=0xfff8;break; + case 14:ar[i]=0xfffc;break; + case 15:ar[i]=0xfffe;break; + default:ar[i]=0;break; + } + prf-=16; + } + return ar; +} +function ip6mask(ip,prf){ + if(typeof(prf)=="number")prf=ip6prefixToMask(prf); + var ip2=new Array; + for(var i=0;i<8;i++)ip2[i] = ip[i] & prf[i]; + return ip2; +} + +function ip6maskHost(ip,prf){ + if(typeof(prf)=="number")prf=ip6prefixToMask(prf); + else prf=ip6copy(prf); + for(var i=0;i<8;i++)prf[i]=(~prf[i])&0xffff; + var ip2=new Array; + for(var i=0;i<8;i++)ip2[i] = ip[i] & prf[i]; + return ip2; +} +function ip6copy(ip){ + var r=new Array; + for(var i=0;i<8;i++)r[i]=ip[i]; + return r; +} +function ip6merge(net,host,prefix){ + net=ip6mask(net,prefix); + host=ip6maskHost(host,prefix); + for(var i=0;i<8;i++)net[i] |= host[i]; + return net; +} +function extractmac(ip6,strsplit){ + if((ip6[5]&0xff)!=0xff || (ip6[6]>>8)!=0xfe)return; + var mac=dec2hexlen((ip6[4]>>8)^2,2)+strsplit; + mac+=dec2hexlen(ip6[4]&0xff,2)+strsplit; + mac+=dec2hexlen(ip6[5]>>8,2)+strsplit; + mac+=dec2hexlen(ip6[6]&0xff,2)+strsplit; + mac+=dec2hexlen(ip6[7]>>8,2)+strsplit; + mac+=dec2hexlen(ip6[7]&0xff,2); + return mac; +} +function mactoeui(value){ + var mac=value.replace(/:/g,"-").split("-"); + if(mac.length!=6){return;} + var ip6=ip6null(); + ip6[4]=hex2dec(mac[0])<<8 | hex2dec(mac[1]); + ip6[4] ^= 0x200; + ip6[5]=hex2dec(mac[2])<<8 | 0xff; + ip6[6]=hex2dec(mac[3]) | 0xfe00; + ip6[7]=hex2dec(mac[4])<<8 | hex2dec(mac[5]); + return ip6toString(ip6); +} +function _toMAC(value,strsplit){ + if(!strsplit) + strsplit = ':'; + return extractmac(parseIp6(value),strsplit); +} +function _toIPv6(prefix,mac,prf){ + if(!mac) + return mactoeui(prefix); + else{ + if(!prf) + prf=64; + return ip6toString(ip6merge(parseIp6(prefix),parseIp6(mactoeui(mac)),parseInt(prf))); + } +} +function _fromIPv6(ip6,prf){ + if(!prf) + prf=64; + ip=parseIp6(ip6); + prf =parseInt(prf); + return { + net:ip6toString(ip6mask(ip,prf)), + host:ip6toString(ip6maskHost(ip,prf)), + mac:_toMAC(ip6) + } +} +module.exports = {toMAC:_toMAC,toIPv6:_toIPv6,fromIPv6:_fromIPv6};