1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277
| #include “stdio.h” #include “string.h” #define QQWRY “QQWry.dat” #define REDIRECT_MODE_1 0×01 #define REDIRECT_MODE_2 0×02 #define MAXBUF 255
/*unsigned long getValue( 获取文件中指定的16进制串的值,并返回 FILE *fp, 指定文件指针 unsigned long start, 指定文件偏移量 int length) 获取的16进制字符个数/长度 */ unsigned long getValue(FILE *fp, unsigned long start, int length) { unsigned long variable=0; long val[length],i;
fseek(fp,start,SEEK_SET); for(i=0;i { /*过滤高位,一次读取一个字符*/ val[i]=fgetc(fp)&0x000000FF; } for(i=length-1;i>=0;i–) { /*因为读取多个16进制字符,叠加*/ variable=variable*0×100+val[i]; } return variable; };
/*int getString( 获取文件中指定的字符串,返回字符串长度 FILE *fp, 指定文件指针 unsigned long start, 指定文件偏移量 char **string) 用来存放将读取字符串的字符串空间的首地址 */ int getString(FILE *fp, unsigned long start, char **string) { unsigned long i=0; char val; fseek(fp,start,SEEK_SET); /*读取字符串,直到遇到0×00为止*/ do { val=fgetc(fp); /*依次放入用来存储的字符串空间中*/ *(*string+i)=val; i++; }while(val!=0×00); /*返回字符串长度*/ return i; };
/*void getAddress( 读取指定IP的国家位置和地域位置 FILE *fp, 指定文件指针 unsigned long start, 指定IP在索引中的文件偏移量 char **country, 用来存放国家位置的字符串空间的首地址 char **location) 用来存放地域位置的字符串空间的首地址 */ void getAddress(FILE *fp, unsigned long start, char **country, char **location) { unsigned long redirect_address,counrty_address,location_address; char val;
start+=4; fseek(fp,start,SEEK_SET); /*读取首地址的值*/ val=(fgetc(fp)&0x000000FF);
if(val==REDIRECT_MODE_1) { /*重定向1类型的*/ redirect_address=getValue(fp,start+1,3); fseek(fp,redirect_address,SEEK_SET); /*混合类型,重定向1类型进入后遇到重定向2类型 读取重定向后的内容,并设置地域位置的文件偏移量*/ if((fgetc(fp)&0x000000FF)==REDIRECT_MODE_2) { counrty_address=getValue(fp,redirect_address+1,3); location_address=redirect_address+4; getString(fp,counrty_address,country); } /*读取重定向1后的内容,并设置地域位置的文件偏移量*/ else { counrty_address=redirect_address; location_address=redirect_address+getString(fp,counrty_address,country); } } /*重定向2类型的*/ else if(val==REDIRECT_MODE_2) { counrty_address=getValue(fp,start+1,3); location_address=start+4; getString(fp,counrty_address,country); } else { counrty_address=start; location_address=counrty_address+getString(fp,counrty_address,country); }
/*读取地域位置*/ fseek(fp,location_address,SEEK_SET); if((fgetc(fp)&0x000000FF)==REDIRECT_MODE_2||(fgetc(fp)&0x000000FF)==REDIRECT_MODE_1) { location_address=getValue(fp,location_address+1,3); } getString(fp,location_address,location);
return; };
/*void getHead( 读取索引部分的范围(在文件头中,最先的2个8位16进制) FILE *fp, 指定文件指针 unsigned long *start, 文件偏移量,索引的起止位置 unsigned long *end) 文件偏移量,索引的结束位置 */ void getHead(FILE *fp,unsigned long *start,unsigned long *end) { /*索引的起止位置的文件偏移量,存储在文件头中的前8个16进制中 设置偏移量为0,读取4个字符*/ *start=getValue(fp,0L,4); /*索引的结束位置的文件偏移量,存储在文件头中的第8个到第15个的16进制中 设置偏移量为4个字符,再读取4个字符*/ *end=getValue(fp,4L,4); };
/*unsigned long searchIP( 搜索指定IP在索引区的位置,采用二分查找法; 返回IP在索引区域的文件偏移量 一条索引记录的结果是,前4个16进制表示起始IP地址 后面3个16进制,表示该起始IP在IP信息段中的位置,文件偏移量 FILE *fp, unsigned long index_start, 索引起始位置的文件偏移量 unsigned long index_end, 索引结束位置的文件偏移量 unsigned long ip) 关键字,要索引的IP */ unsigned long searchIP(FILE *fp, unsigned long index_start,
unsigned long index_end, unsigned long ip) { unsigned long index_current,index_top,index_bottom; unsigned long record; index_bottom=index_start; index_top=index_end; /*此处的7,是因为一条索引记录的长度是7*/ index_current=((index_top-index_bottom)/7/2)*7+index_bottom; /*二分查找法*/ do{ record=getValue(fp,index_current,4); if(record>ip) { index_top=index_current; index_current=((index_top-index_bottom)/14)*7+index_bottom; } else { index_bottom=index_current; index_current=((index_top-index_bottom)/14)*7+index_bottom; } }while(index_bottom /*返回关键字IP在索引区域的文件偏移量*/ return index_current; };
/*unsigned long putAll( 导出所有IP信息到文件文件中,函数返回导出总条数 FILE *fp, FILE *out, 导出的文件指针,必须拥有写权限 unsigned long index_start, 索引区域的起始文件偏移量 unsigned long index_end) 索引区域的结束文件偏移量 */ unsigned long putAll(FILE *fp, FILE *out, unsigned long index_start, unsigned long index_end) { unsigned long i,count=0; unsigned long start_ip,end_ip; char *country; char *location;
country=(char*)malloc(255); location=(char*)malloc(255);
/*此处的7,是因为一条索引记录的长度是7*/ for(i=index_start;i { /*获取IP段的起始IP和结束IP,
起始IP为索引部分的前4位16进制 结束IP在IP信息部分的前4位16进制中,靠索引部分指定的偏移量找寻*/ start_ip=getValue(fp,i,4); end_ip=getValue(fp,getValue(fp,i+4,3),4); /*导出IP信息,格式是 起始IPt结束IPt国家位置t地域位置n*/ fprintf(out,”%d.%d.%d.%d”,(start_ip&0xFF000000)>>0×18,
(start_ip&0x00FF0000)>>0×10,(start_ip&0x0000FF00)>>0×8,start_ip&0x000000FF); fprintf(out,”t”); fprintf(out,”%d.%d.%d.%d”,(end_ip&0xFF000000)>>0×18,
(end_ip&0x00FF0000)>>0×10,(end_ip&0x0000FF00)>>0×8,end_ip&0x000000FF); getAddress(fp,getValue(fp,i+4,3),&country,&location); fprintf(out,”t%st%sn”,country,location); count++; } /*返回导出总条数*/ return count; };
/*判断一个字符是否为数字字符, 如果是,返回0 如果不是,返回1*/ int beNumber(char c) { if(c>=’0′&&c< ='9') return 0; else return 1; };
/*函数的参数是一个存储着IP地址的字符串首地址 返回该IP的16进制代码 如果输入的IP地址有错误,函数将返回0*/ unsigned long getIP(char *ip_addr) { unsigned long ip=0; int i,j=0; /*依次读取字符串中的各个字符*/ for(i=0;i { /*如果是IP地址间隔的‘.’符号 把当前读取到的IP字段的值,存入ip变量中 (注意,ip为叠加时,乘以16进制的0×100) 并清除临时变量的值*/ if(*(ip_addr+i)==’.') { ip=ip*0×100+j; j=0; } /*往临时变量中写入当前读取到的IP字段中的字符值 叠加乘以10,因为输入的IP地址是10进制*/ else { /*判断,如果输入的IP地址不规范,不是10进制字符 函数将返回0*/ if(beNumber(*(ip_addr+i))==0) j=j*10+*(ip_addr+i)-’0′; else return 0; } } /*IP字段有4个,但是‘.’只有3个,叠加第四个字段值*/ ip=ip*0×100+j; return ip; };
/*显示logo信息*/ void logo(void) { printf(“=============================================================================n”); printf(“— Get the IP info.s from QQWry.dat v0.1 by dorainm dorainm@gmail.com —n”); printf(“=============================================================================n”);
};
/*显示程序语法*/ void usage(char *app_name) { printf(“nUsage : %s [options]n”,app_name); printf(“options:n”); printf(” -a Search and display the Informations by Location Address.(*)n”); printf(” -i Search and display the Informations by IP Address.n”); printf(” -o Output all the informations to a text file.n”); printf(” -local Display the localhost IP’s informations.(*)n”); printf(” -updata Update the QQWry.dat from the Internet.(*)nn”); printf(“ps: the optionss marked (*) are incompleted.n”); }; /*显示结束信息*/ void showend(void) { printf(“nnThe command completed successfully.nn”); };
|