whois和运营商的故事

wwwchinabignet 2011-11-10

有一个业务需求:

根据来访的IP,判断其所属运营商,根据运营商的不同,展示不同的东西。

然后,各种找资料。

刚开始找到一个: 纯真IP

>>这个··· 首先对制作这个IP数据库的人致敬,但是,数据不符合需求,因为,我们需要运营商。

然后又找到一个: APNIC

>>这个··· 由于linux中已经提供了相关的命令--whois(没有提供的可以自己安装,到apnic的网站上下载就行,不叙),

>>所以,就像很多其他文章(google:apnic whois 运营商)中说的似的,貌似,编写个脚本,分析一下数据,就可以得

>>到各运营商的IP段,但是,whois返回的详细信息太不规范,用这种狗血的信息分析,无疑是自杀。

>>再者,中国的运营商,那叫一个乱起八糟,不说了···

然后又找到一个:ip138

>>仔细看了一下,这个网站查询出的东西,挺准确的,要不自己写个抓取程序?嗯,先试试吧···

------------------------------华丽丽---------------------------------

最终还是选择了权威的APNIC

从这个网页上可以找到中国的IP段(网页上给出了提示,说可能不是很全、很新····不过,凑合着用吧):http://ftp.apnic.net/apnic/stats/apnic/delegated-apnic-latest

附上此网页中数据的说明:

1、在网页中查找“|CN|ipv4|”,匹配的行即为天朝IP地址段信息。

2、拿其中一条数据做说明,比如这条:

apnic|CN|ipv4|60.55.0.0|65536|20040802|allocated

     我们看以“|”做区分后的第四个和第五个值,即:60.55.0.0和65536。其他的值可以不用管了

     这两个值组合起来其实可以这么表示:60.55.0.0/16,这种方式叫CIDR,表示的是一个网段,我也一知半解的,

这里就不多说了,对于网络基础一般的童鞋来说,就可以这样理解:从60.55.0.0,后面65536个IP都是这个网段

     的,这就够了。

那么可以开始了,先是写一个shell,去读取这个网页,然后调用whois,分析返回回来的字符串,判断IP段所属运营商。

#!/bin/sh
DIR=/data/ip
APNIC=$DIR/apnic
CNNET=$DIR/cnnet
ctc=$DIR/ctc
cucc=$DIR/cucc
cmcc=$DIR/cmcc

rm -f $APNIC
rm -f $CNNET
rm -f $ctc
rm -f $cucc
rm -f $cmcc

wget http://ftp.apnic.net/apnic/stats/apnic/delegated-apnic-latest -O $APNIC
grep '|CN|ipv4|' $APNIC | cut -f 4,5 -d'|'|sed -e 's/|/ /g' | while read ip submask
do
        echo $ip/$submask
        echo $ip/$submask >> $CNNET
        NETNAME=`whois $ip | grep -e ^netname -e ^mnt-by -e ^mnt-lower -e ^descr | sed -e 's/.*:      (.*)/1/g' | sed -e 's/-.*//g'`

        if echo $NETNAME | grep -i -e 'CHINANET' -e 'CHINATELECOM'
                then echo $ip/$submask >> $ctc
        elif echo $NETNAME | grep -i -e 'UNICOM' -e 'CNC' -e 'CNCGROUP'
                then echo $ip/$submask >> $cucc
        elif echo $NETNAME | grep -i -e 'CMNET' -e 'CMCC' -e 'MOBILE'
                then echo $ip/$submask >> $cmcc
        fi
done

这样,执行完这个shell后,不同的运营商IP信息就在相应的文件中了。

然后,从写一个java程序,去读取上面的文件,然后根据实际情况处理就行了。

下面贴出最主要的代码:

long f = Utils.ip2Long(from); // from 即上面的60.55.0.0
long t = f + Long.parseLong(count) - 1;	// count 即上面的65536

// 下面贴出IP的字符串和长整型相互转换的方法

/**
 * 将形如127.0.0.1的IP转换为其所对应的长整型数值
 * 说明:
 * 		无任何校验及异常捕获,请传入正确的IP字符串
 */
public static long ip2Long(String ipStr) {
	long[] ipLong = new long[4];
	String[] off = ipStr.split("\\.");
	ipLong[0] = Long.parseLong(off[0]) << 24;
	ipLong[1] = Long.parseLong(off[1]) << 16;
	ipLong[2] = Long.parseLong(off[2]) << 8;
	ipLong[3] = Long.parseLong(off[3]);
	
	return ipLong[0] + ipLong[1] + ipLong[2] + ipLong[3];
}

/**
 * 将长整型数值的IP转换为其所对应的形如127.0.0.1的字符串
 * 说明:
 * 		无任何校验及异常捕获,请传入正确的IP长整数
 */
public static String long2Ip(long ipLong) {
	StringBuilder ip = new StringBuilder();
	ip.append(ipLong >>> 24).append(".");
	ip.append((ipLong & 0x00FFFFFF) >>> 16).append(".");
	ip.append((ipLong & 0x0000FFFF) >>> 8).append(".");
	ip.append((ipLong & 0x000000FF));
	
	return ip.toString();
}
 

网上闲逛,看到一个java调用whois的程序,用了apache commons 的 net 包,强大的apache!

相关推荐