QQ登录

只需一步,快速开始

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 6419|回复: 3

读取纯真IP数据库 showip

[复制链接]
发表于 2007-7-31 04:30:17 | 显示全部楼层 |阅读模式
关于 纯真IP数据库格式,详细见下面帖子:

http://blog.chinaunix.net/u1/41420/showart_322320.html


程序说明:能够根据输入的IP,在 纯真IP数据库 中,搜索并且读取对应的 物理地址,还可以导出所有的IP段地址信息

函数部分

  1. #include "stdio.h"

  2. #include "string.h"



  3. #define QQWRY "QQWry.dat"

  4. #define REDIRECT_MODE_1 0x01

  5. #define REDIRECT_MODE_2 0x02

  6. #define MAXBUF 255



  7. /*unsigned long getValue(                获取文件中指定的16进制串的值,并返回

  8.         FILE *fp,                        指定文件指针

  9.         unsigned long start,                指定文件偏移量

  10.         int length)                        获取的16进制字符个数/长度

  11. */

  12. unsigned long getValue(FILE *fp, unsigned long start, int length)

  13. {

  14.         unsigned long variable=0;

  15.         long val[length],i;



  16.         fseek(fp,start,SEEK_SET);

  17.         for(i=0;i<length;i++)

  18.         {

  19.                 /*过滤高位,一次读取一个字符*/

  20.                 val=fgetc(fp)&0x000000FF;

  21.         }        

  22.         for(i=length-1;i>=0;i--)

  23.         {

  24.                 /*因为读取多个16进制字符,叠加*/

  25.                 variable=variable*0x100+val;

  26.         }        

  27.         return variable;

  28. };





  29. /*int getString(                        获取文件中指定的字符串,返回字符串长度

  30.         FILE *fp,                        指定文件指针

  31.         unsigned long start,                指定文件偏移量

  32.         char **string)                        用来存放将读取字符串的字符串空间的首地址

  33. */

  34. int getString(FILE *fp, unsigned long start, char **string)

  35. {

  36.         unsigned long i=0;

  37.         char val;

  38.         fseek(fp,start,SEEK_SET);

  39.         /*读取字符串,直到遇到0x00为止*/

  40.         do

  41.         {

  42.                 val=fgetc(fp);

  43.                 /*依次放入用来存储的字符串空间中*/

  44.                 *(*string+i)=val;

  45.                 i++;

  46.         }while(val!=0x00);

  47.         /*返回字符串长度*/

  48.         return i;

  49. };





  50. /*void getAddress(                        读取指定IP的国家位置和地域位置

  51.         FILE *fp,                        指定文件指针

  52.         unsigned long start,                指定IP在索引中的文件偏移量

  53.         char **country,                        用来存放国家位置的字符串空间的首地址

  54.         char **location)                用来存放地域位置的字符串空间的首地址

  55. */

  56. void getAddress(FILE *fp, unsigned long start, char **country, char **location)

  57. {

  58.         unsigned long redirect_address,counrty_address,location_address;

  59.         char val;

  60.         

  61.         start+=4;

  62.         fseek(fp,start,SEEK_SET);

  63.         /*读取首地址的值*/

  64.         val=(fgetc(fp)&0x000000FF);



  65.         if(val==REDIRECT_MODE_1)

  66.         {

  67.                 /*重定向1类型的*/

  68.                 redirect_address=getValue(fp,start+1,3);

  69.                 fseek(fp,redirect_address,SEEK_SET);

  70.                 /*混合类型,重定向1类型进入后遇到重定向2类型

  71.                   读取重定向后的内容,并设置地域位置的文件偏移量*/

  72.                 if((fgetc(fp)&0x000000FF)==REDIRECT_MODE_2)

  73.                 {

  74.                         counrty_address=getValue(fp,redirect_address+1,3);

  75.                         location_address=redirect_address+4;

  76.                         getString(fp,counrty_address,country);

  77.                 }

  78.                 /*读取重定向1后的内容,并设置地域位置的文件偏移量*/

  79.                 else

  80.                 {

  81.                         counrty_address=redirect_address;

  82.                         location_address=redirect_address+getString(fp,counrty_address,country);

  83.                 }

  84.         }

  85.         /*重定向2类型的*/

  86.         else if(val==REDIRECT_MODE_2)

  87.         {

  88.                 counrty_address=getValue(fp,start+1,3);

  89.                 location_address=start+4;

  90.                 getString(fp,counrty_address,country);

  91.         }

  92.         else

  93.         {

  94.                 counrty_address=start;

  95.                 location_address=counrty_address+getString(fp,counrty_address,country);

  96.         }

  97.         

  98.         /*读取地域位置*/

  99.         fseek(fp,location_address,SEEK_SET);

  100.         if((fgetc(fp)&0x000000FF)==REDIRECT_MODE_2||(fgetc(fp)&0x000000FF)==REDIRECT_MODE_1)

  101.         {

  102.         location_address=getValue(fp,location_address+1,3);

  103.         }

  104.         getString(fp,location_address,location);



  105.         return;

  106. };





  107. /*void getHead(                                        读取索引部分的范围(在文件头中,最先的2个8位16进制)

  108.         FILE *fp,                                指定文件指针

  109.         unsigned long *start,                        文件偏移量,索引的起止位置

  110.         unsigned long *end)                        文件偏移量,索引的结束位置

  111. */

  112. void getHead(FILE *fp,unsigned long *start,unsigned long *end)

  113. {

  114.         /*索引的起止位置的文件偏移量,存储在文件头中的前8个16进制中

  115.           设置偏移量为0,读取4个字符*/

  116.         *start=getValue(fp,0L,4);

  117.         /*索引的结束位置的文件偏移量,存储在文件头中的第8个到第15个的16进制中

  118.           设置偏移量为4个字符,再读取4个字符*/

  119.         *end=getValue(fp,4L,4);

  120. };





  121. /*unsigned long searchIP(                        搜索指定IP在索引区的位置,采用二分查找法;

  122.                                                         返回IP在索引区域的文件偏移量

  123.                                                         一条索引记录的结果是,前4个16进制表示起始IP地址

  124.                                                         后面3个16进制,表示该起始IP在IP信息段中的位置,文件偏移量

  125.         FILE *fp,

  126.         unsigned long index_start,                索引起始位置的文件偏移量

  127.         unsigned long index_end,                索引结束位置的文件偏移量

  128.         unsigned long ip)                        关键字,要索引的IP

  129. */

  130. unsigned long searchIP(FILE *fp, unsigned long index_start, unsigned long index_end, unsigned long ip)

  131. {

  132.         unsigned long index_current,index_top,index_bottom;

  133.         unsigned long record;

  134.         index_bottom=index_start;

  135.         index_top=index_end;

  136.         /*此处的7,是因为一条索引记录的长度是7*/

  137.         index_current=((index_top-index_bottom)/7/2)*7+index_bottom;

  138.         /*二分查找法*/

  139.         do{

  140.                 record=getValue(fp,index_current,4);

  141.                 if(record>ip)

  142.                 {

  143.                         index_top=index_current;

  144.                         index_current=((index_top-index_bottom)/14)*7+index_bottom;

  145.                 }

  146.                 else

  147.                 {

  148.                         index_bottom=index_current;

  149.                         index_current=((index_top-index_bottom)/14)*7+index_bottom;

  150.                 }

  151.         }while(index_bottom<index_current);

  152.         /*返回关键字IP在索引区域的文件偏移量*/

  153.         return index_current;

  154. };





  155. /*unsigned long putAll(                                导出所有IP信息到文件文件中,函数返回导出总条数

  156.         FILE *fp,

  157.         FILE *out,                                导出的文件指针,必须拥有写权限

  158.         unsigned long index_start,                索引区域的起始文件偏移量

  159.         unsigned long index_end)                索引区域的结束文件偏移量

  160. */

  161. unsigned long putAll(FILE *fp, FILE *out, unsigned long index_start, unsigned long index_end)

  162. {

  163.         unsigned long i,count=0;

  164.         unsigned long start_ip,end_ip;

  165.         char *country;

  166.         char *location;

  167.         

  168.         country=(char*)malloc(255);

  169.         location=(char*)malloc(255);

  170.         

  171.         /*此处的7,是因为一条索引记录的长度是7*/

  172.         for(i=index_start;i<index_end;i+=7)

  173.         {

  174.                 /*获取IP段的起始IP和结束IP,

  175.                   起始IP为索引部分的前4位16进制

  176.                   结束IP在IP信息部分的前4位16进制中,靠索引部分指定的偏移量找寻*/

  177.                 start_ip=getValue(fp,i,4);

  178.                 end_ip=getValue(fp,getValue(fp,i+4,3),4);

  179.                 /*导出IP信息,格式是

  180.                   起始IP\t结束IP\t国家位置\t地域位置\n*/

  181.                 fprintf(out,"%d.%d.%d.%d",(start_ip&0xFF000000)>>0x18,(start_ip&0x00FF0000)>>0x10,(start_ip&0x0000FF00)>>0x8,start_ip&0x000000FF);

  182.                 fprintf(out,"\t");

  183.                 fprintf(out,"%d.%d.%d.%d",(end_ip&0xFF000000)>>0x18,(end_ip&0x00FF0000)>>0x10,(end_ip&0x0000FF00)>>0x8,end_ip&0x000000FF);

  184.                 getAddress(fp,getValue(fp,i+4,3),&country,&location);

  185.                 fprintf(out,"\t%s\t%s\n",country,location);

  186.                 count++;

  187.         }

  188.         /*返回导出总条数*/

  189.         return count;

  190. };





  191. /*判断一个字符是否为数字字符,

  192.   如果是,返回0

  193.   如果不是,返回1*/

  194. int beNumber(char c)

  195. {

  196.         if(c>='0'&&c<='9')

  197.                 return 0;

  198.         else

  199.                 return 1;

  200. };

复制代码

[ 本帖最后由 dorainm 于 2007-7-31 04:32 编辑 ]
 楼主| 发表于 2007-7-31 04:33:39 | 显示全部楼层




  1. /*函数的参数是一个存储着IP地址的字符串首地址

  2.   返回该IP的16进制代码

  3.   如果输入的IP地址有错误,函数将返回0*/

  4. unsigned long getIP(char *ip_addr)

  5. {

  6.         unsigned long ip=0;

  7.         int i,j=0;

  8.         /*依次读取字符串中的各个字符*/

  9.         for(i=0;i<strlen(ip_addr);i++)

  10.         {

  11.                 /*如果是IP地址间隔的‘.’符号

  12.                   把当前读取到的IP字段的值,存入ip变量中

  13.                   (注意,ip为叠加时,乘以16进制的0x100)

  14.                   并清除临时变量的值*/

  15.                 if(*(ip_addr+i)=='.')

  16.                 {

  17.                         ip=ip*0x100+j;

  18.                         j=0;

  19.                 }

  20.                 /*往临时变量中写入当前读取到的IP字段中的字符值

  21.                   叠加乘以10,因为输入的IP地址是10进制*/

  22.                 else

  23.                 {

  24.                         /*判断,如果输入的IP地址不规范,不是10进制字符

  25.                           函数将返回0*/

  26.                         if(beNumber(*(ip_addr+i))==0)

  27.                                 j=j*10+*(ip_addr+i)-'0';

  28.                         else

  29.                                 return 0;

  30.                 }

  31.         }

  32.         /*IP字段有4个,但是‘.’只有3个,叠加第四个字段值*/

  33.         ip=ip*0x100+j;

  34.         return ip;

  35. };





  36. /*显示logo信息*/

  37. void logo(void)

  38. {

  39.         printf("=============================================================================\n");

  40.         printf("--- Get the IP info.s from QQWry.dat v0.1   by dorainm  [email][email protected][/email] ---\n");

  41.         printf("=============================================================================\n");

  42. };





  43. /*显示程序语法*/

  44. void usage(char *app_name)

  45. {

  46.         printf("\nUsage : %s [options]\n",app_name);

  47.         printf("options:\n");

  48.         printf("  -a <address>    Search and display the Informations by Location Address.(*)\n");

  49.         printf("  -i <IP>         Search and display the Informations by IP Address.\n");

  50.         printf("  -o <FILE>       Output all the informations to a text file.\n");

  51.         printf("  -local          Display the localhost IP's informations.(*)\n");

  52.         printf("  -updata         Update the QQWry.dat from the Internet.(*)\n\n");

  53.         printf("ps:  the optionss marked (*) are incompleted.\n");

  54. };





  55. /*显示结束信息*/

  56. void showend(void)

  57. {

  58.         printf("\n\nThe command completed successfully.\n\n");

  59. };
复制代码
回复

使用道具 举报

 楼主| 发表于 2007-7-31 04:34:01 | 显示全部楼层
main函数部分

  1. /*主函数*/

  2. int main(int argc, char *argv[])

  3. {

  4.         FILE *fp;                                                /*打开QQWry.dat的文件指针*/

  5.         unsigned long index_start,index_end,current;                /*索引部分的起始位置的文件偏移量

  6.                                                                   索引部分的结束位置的文件偏移量

  7.                                                                   待搜索IP地址的索引条目的文件偏移量*/

  8.         char *country;                                                /*国家位置*/

  9.         char *location;                                                /*地域位置*/

  10.         country=(char*)malloc(MAXBUF);

  11.         location=(char*)malloc(MAXBUF);

  12.         

  13.         logo();

  14.         if(argc<3)

  15.         {

  16.                 usage(argv[0]);

  17.                 showend();

  18.                 return 1;

  19.         }        

  20.         

  21.         /*打开QQWry.dat文件*/

  22.         if((fp=fopen(QQWRY,"rb"))==NULL)

  23.         {

  24.                 printf("[-]  Error : Can not open the file %s.\n",QQWRY);

  25.                 showend();

  26.                 return 2;

  27.         }

  28.         else

  29.                 printf("[+]  Open the file [ %s ] successfully.\n",QQWRY);



  30.         /*显示QQWry.dat文件信息*/

  31.         getHead(fp,&index_start,&index_end);

  32.         getAddress(fp,getValue(fp,index_end+4,3),&country,&location);

  33.         printf("[+]  Version of QQWry.dat : [ %s %s ]\n",country,location);

  34.         printf("[+]  Index Location [ 0x%X - 0x%X ].\n",index_start,index_end);

  35.         

  36.         /*判断第一个参数的值*/

  37.         if((strncmp(argv[1],"-i",2)==0)||(strncmp(argv[1],"-I",2)==0))

  38.         {

  39.                 /*-i参数,搜索IP*/

  40.                 unsigned long ip;



  41.                 ip=getIP(argv[2]);

  42.                 if(ip==0)

  43.                 {

  44.                         printf("[-]  Error : the IP Address inputed.\n");

  45.                         showend();

  46.                         return 3;

  47.                 }



  48.                 /*搜索IP在索引区域的条目的偏移量*/

  49.                 current=searchIP(fp,index_start,index_end,ip);

  50.                 printf("[+]  Address of index for [ %X ] is %X\n",ip,current);



  51.                 /*获取该IP对因的国家地址和地域地址*/

  52.                 getAddress(fp,getValue(fp,current+4,3),&country,&location);

  53.                 printf("[+]  Get the location for the IP address.\n");

  54.                 printf("[+]  [ IP Address ] %d.%d.%d.%d\n",(ip&0xFF000000)>>0x18,(ip&0x00FF0000)>>0x10,(ip&0x0000FF00)>>0x8,ip&0x000000FF);

  55.                 printf("[+]  [  Location  ] %s %s\n",country,location);

  56.         }

  57.         else if((strncmp(argv[1],"-o",2)==0)||(strncmp(argv[1],"-O",2)==0))

  58.         {

  59.                 /*-o参数,解压缩数据库,导出IP信息到文本文件*/

  60.                 FILE *out;

  61.                 unsigned long num;

  62.                 if((out=fopen(argv[2],"w"))==NULL)

  63.                 {

  64.                         printf("[-]  Error create the output text file [ %s ].\n","out.txt");

  65.                         showend();

  66.                 }

  67.                 else

  68.                 {

  69.                         printf("[+]  Create the output text file [ %s ] successfully.\n","out.txt");

  70.                 }



  71.                 /*导出IP条目信息*/

  72.                 printf("[+]  Outputing the informations ...");

  73.                 num=putAll(fp,out,index_start,index_end);

  74.                 printf("Finished.\n");

  75.                 fclose(out);

  76.                 /*显示导出条目的数量*/

  77.                 printf("[+]  The Total items number is [ %d ].",num);

  78.         }

  79.         /*关闭文件指针,释放变量空间,结束程序*/

  80.         fclose(fp);

  81.         free(country);

  82.         free(location);

  83.         showend();

  84.         return 0;

  85. }
复制代码


使用语法
=============================================================================
--- Get the IP info.s from QQWry.dat v0.1   by dorainm  [email protected] ---
=============================================================================

Usage : showip [options]
options:
  -a <address>    Search and display the Informations by Location Address.(*)
  -i <IP>         Search and display the Informations by IP Address.
  -o <FILE>       Output all the informations to a text file.
  -local          Display the localhost IP's informations.(*)
  -updata         Update the QQWry.dat from the Internet.(*)

ps:  the optionss marked (*) are incompleted.


The command completed successfully.


搜索IP
showip -i 222.19.211.254

=============================================================================
--- Get the IP info.s from QQWry.dat v0.1   by dorainm  [email protected] ---
=============================================================================
[+]  Open the file [ QQWry.dat ] successfully.
[+]  Version of QQWry.dat : [ 纯真网络 2006年3月5日IP数据 ]
[+]  Index Location [ 0x37A265 - 0x535EB1 ].
[+]  Address of index for [ DE13D3FE ] is 51BB44
[+]  Get the location for the IP address.
[+]  [ IP Address ] 222.19.211.254
[+]  [  Location  ] 云南大学 国家示范性软件学院


The command completed successfully.


导出所有IP信息,语法是 showip -o out.txt

其余功能有待完成


程序在 gcc3.3.1 中编译通过

如果移植到 microsoft windows 下,使用 VC 编译器,

可能需要把main函数中所有的变量申明语句移动到main函数的 logo(); 语句前面

(遥远记得以前,我在win2000下用VC++6.0,好像需要先申请再执行语句
不然编译没法通过...)
回复

使用道具 举报

发表于 2007-8-3 23:31:08 | 显示全部楼层
个人觉得这个东西意义还不是很大。。。
知道ip就已经可以了。。。

对方要是用代理呢。。。

但是用于练习还是很不错的
再次赞lz
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

GMT+8, 2024-4-19 08:19 , Processed in 0.053997 second(s), 15 queries .

© 2021 Powered by Discuz! X3.5.

快速回复 返回顶部 返回列表