forked from flanchan/doushio
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
195 lines
4.6 KiB
195 lines
4.6 KiB
5 years ago
|
var _ = require('../lib/underscore');
|
||
|
var config = require('../config');
|
||
|
var common = require('../common');
|
||
|
|
||
|
var DEFINES = exports;
|
||
|
DEFINES.FETCH_ADDRESS = 101;
|
||
|
DEFINES.SET_ADDRESS_NAME = 102;
|
||
|
DEFINES.BAN = 103;
|
||
|
|
||
|
var modCache = {}; // TEMP
|
||
|
exports.modCache = modCache;
|
||
|
|
||
|
var suspensionKeys = ['boxes', 'bans', 'slows', 'suspensions', 'timeouts'];
|
||
|
exports.suspensionKeys = suspensionKeys;
|
||
|
|
||
|
var delayNames = ['now', 'soon', 'later'];
|
||
|
var delayDurations = {now: 0, soon: 60, later: 20*60};
|
||
|
exports.delayDurations = delayDurations;
|
||
|
|
||
|
var mnemonicStarts = ',k,s,t,d,n,h,b,p,m,f,r,g,z,l,ch'.split(',');
|
||
|
var mnemonicEnds = "a,i,u,e,o,a,i,u,e,o,ya,yi,yu,ye,yo,'".split(',');
|
||
|
|
||
|
function ip_mnemonic(ip) {
|
||
|
if (/^[a-fA-F0-9:]{3,45}$/.test(ip))
|
||
|
return ipv6_mnemonic(ip);
|
||
|
if (!is_IPv4_ip(ip))
|
||
|
return null;
|
||
|
var nums = ip.split('.');
|
||
|
var mnemonic = '';
|
||
|
for (var i = 0; i < 4; i++) {
|
||
|
var n = parseInt(nums[i], 10);
|
||
|
var s = mnemonicStarts[Math.floor(n / 16)] +
|
||
|
mnemonicEnds[n % 16];
|
||
|
mnemonic += s;
|
||
|
}
|
||
|
return mnemonic;
|
||
|
}
|
||
|
|
||
|
var ipv6kana = (
|
||
|
',a,i,u,e,o,ka,ki,' +
|
||
|
'ku,ke,ko,sa,shi,su,se,so,' +
|
||
|
'ta,chi,tsu,te,to,na,ni,nu,' +
|
||
|
'ne,no,ha,hi,fu,he,ho,ma,' +
|
||
|
'mi,mu,me,mo,ya,yu,yo,ra,' +
|
||
|
'ri,ru,re,ro,wa,wo,ga,gi,' +
|
||
|
'gu,ge,go,za,ji,zu,ze,zo,' +
|
||
|
'da,de,do,ba,bi,bu,be,bo'
|
||
|
).split(',');
|
||
|
if (ipv6kana.length != 64)
|
||
|
throw new Error('bad ipv6 kana!');
|
||
|
|
||
|
var ipv6alts = {
|
||
|
sa: 'sha', su: 'shu', so: 'sho',
|
||
|
ta: 'cha', tsu: 'chu', to: 'cho',
|
||
|
fu: 'hyu',
|
||
|
za: 'ja', zu: 'ju', zo: 'jo',
|
||
|
};
|
||
|
|
||
|
function ipv6_mnemonic(ip) {
|
||
|
var groups = explode_IPv6_ip(ip);
|
||
|
if (!groups || groups.length != 8)
|
||
|
return null;
|
||
|
|
||
|
// takes 8 bits, returns kana
|
||
|
function p(n) {
|
||
|
// bits 0-5 are lookup; 6-7 are modifier
|
||
|
var kana = ipv6kana[n & 0x1f];
|
||
|
if (!kana)
|
||
|
return kana;
|
||
|
var mod = (n >> 6) & 3;
|
||
|
// posibly modify the kana
|
||
|
if (mod > 1 && kana[0] == 'b')
|
||
|
kana = 'p' + kana[1];
|
||
|
if (mod == 3) {
|
||
|
var alt = ipv6alts[kana];
|
||
|
if (alt)
|
||
|
return alt;
|
||
|
var v = kana[kana.length - 1];
|
||
|
if ('knhmrgbp'.indexOf(kana[0]) >= 0 && 'auo'.indexOf(v) >= 0)
|
||
|
kana = kana[0] + 'y' + kana.slice(1);
|
||
|
}
|
||
|
return kana;
|
||
|
}
|
||
|
|
||
|
var ks = groups.map(function (hex) {
|
||
|
var n = parseInt(hex, 16);
|
||
|
return p(n >> 8) + p(n);
|
||
|
});
|
||
|
|
||
|
function cap(s) {
|
||
|
return s[0].toUpperCase() + s.slice(1);
|
||
|
}
|
||
|
|
||
|
// discard first group (RIR etc)
|
||
|
// also discard some other groups for length/anonymity
|
||
|
var sur = ks.slice(1, 4).join('') || 'z';
|
||
|
var given = ks.slice(6, 8).join('') || 'z';
|
||
|
return cap(sur) + ' ' + cap(given);
|
||
|
}
|
||
|
|
||
|
function append_mnemonic(info) {
|
||
|
var header = info.header, ip = info.data.ip;
|
||
|
if (!ip)
|
||
|
return;
|
||
|
var mnemonic = config.IP_MNEMONIC && ip_mnemonic(ip);
|
||
|
var key = ip_key(ip);
|
||
|
|
||
|
// Terrible hack.
|
||
|
if (mnemonic && modCache.addresses) {
|
||
|
var addr = modCache.addresses[key];
|
||
|
if (addr && addr.name)
|
||
|
mnemonic += ' "' + addr.name + '"';
|
||
|
}
|
||
|
|
||
|
var s = common.safe;
|
||
|
var title = mnemonic ? [s(' title="'), ip, s('"')] : '';
|
||
|
header.push(s(' <a class="mod addr"'), title, s('>'),
|
||
|
mnemonic || ip, s('</a>'));
|
||
|
}
|
||
|
|
||
|
function denote_hidden(info) {
|
||
|
if (info.data.hide)
|
||
|
info.header.push(common.safe(
|
||
|
' <em class="mod hidden">(hidden)</em>'));
|
||
|
}
|
||
|
exports.denote_hidden = denote_hidden;
|
||
|
|
||
|
function is_IPv4_ip(ip) {
|
||
|
if (typeof ip != 'string' || !/^\d+\.\d+\.\d+\.\d+$/.exec(ip))
|
||
|
return false;
|
||
|
var nums = ip.split('.');
|
||
|
for (var i = 0; i < 4; i++) {
|
||
|
var n = parseInt(nums[i], 10);
|
||
|
if (n > 255)
|
||
|
return false;
|
||
|
if (n && nums[i][0] == '0')
|
||
|
return false;
|
||
|
}
|
||
|
return true;
|
||
|
}
|
||
|
exports.is_IPv4_ip = is_IPv4_ip;
|
||
|
|
||
|
exports.is_valid_ip = function (ip) {
|
||
|
return typeof ip == 'string' && /^[\da-fA-F.:]{3,45}$/.test(ip);
|
||
|
}
|
||
|
|
||
|
function explode_IPv6_ip(ip) {
|
||
|
if (typeof ip != 'string')
|
||
|
return null;
|
||
|
|
||
|
var groups = ip.split(':');
|
||
|
var gap = groups.indexOf('');
|
||
|
if (gap >= 0 || groups.length != 8) {
|
||
|
// expand ::
|
||
|
if (gap < 0 || gap != groups.lastIndexOf(''))
|
||
|
return null;
|
||
|
var zeroes = [gap, 1];
|
||
|
for (var i = groups.length; i < 9; i++)
|
||
|
zeroes.push('0');
|
||
|
groups.splice.apply(groups, zeroes);
|
||
|
}
|
||
|
|
||
|
// check hex components
|
||
|
for (var i = 0; i < groups.length; i++) {
|
||
|
var n = parseInt(groups[i], 16);
|
||
|
if (_.isNaN(n) || n > 0xffff)
|
||
|
return null;
|
||
|
groups[i] = n.toString(16);
|
||
|
}
|
||
|
|
||
|
return groups;
|
||
|
}
|
||
|
|
||
|
function ip_key(ip) {
|
||
|
if (!is_IPv4_ip(ip)) {
|
||
|
// chop off the last half of IPv6 ips
|
||
|
var bits = explode_IPv6_ip(ip);
|
||
|
if (bits && bits.length == 8)
|
||
|
return bits.slice(0, 4).join(':');
|
||
|
}
|
||
|
return ip;
|
||
|
}
|
||
|
exports.ip_key = ip_key;
|
||
|
|
||
|
if (typeof IDENT != 'undefined') {
|
||
|
/* client */
|
||
|
window.ip_mnemonic = ip_mnemonic;
|
||
|
oneeSama.hook('headerName', append_mnemonic);
|
||
|
oneeSama.hook('headerName', denote_hidden);
|
||
|
}
|
||
|
else {
|
||
|
exports.ip_mnemonic = ip_mnemonic;
|
||
|
exports.append_mnemonic = append_mnemonic;
|
||
|
}
|