#include #include #include char*geofile="/usr/share/ip-geo.ids"; char*ctrycodefile="/usr/share/country-codes.txt"; int showctry=1; int showcode=0; int showip=0; int showrange=0; int showmatches=0; int showeol=1; char matchrange[64]=""; unsigned long str2ip(char*s) { char*sp,*sp1,*sp2; int n1,n2,n3,n4; sp=strchr(s,'.');if(!sp)return 0;sp++; sp1=strchr(sp,'.');if(!sp1)return 0;sp1++; sp2=strchr(sp1,'.');if(!sp2)return 0;sp2++; n1=atoi(s);n2=atoi(sp);n3=atoi(sp1);n4=atoi(sp2); return (n1<<24)+(n2<<16)+(n3<<8)+n4; } unsigned long str2mask(int n) { unsigned long l=0; while(n>0){l>>=1;l|=0x80000000;n--;} return l; } int maskmatch(long ip,long ip2,int mask) { unsigned long m; m=str2mask(mask); return (ip&m) == (ip2&m); } char*code2loc(char*code) { FILE*f; static char s[256]="",*sp,*sp1; f=fopen(ctrycodefile,"r");if(!f)return "[Cannot open countrycode file.]"; while(!feof(f)){ s[0]=0;fgets(s,255,f);if(s[0]=='#')continue; sp=strchr(s,' ');if(!sp)continue;sp[0]=0;sp++;while(sp[0]==' ')sp++; if(strcasecmp(code,s))continue; fclose(f);sp1=strchr(sp,'\n');if(sp1)sp1[0]=0;return sp; } fclose(f);return "(No match.)"; } void printcountry(char*ip,char*code,char*range) { char*sp; if(showip)printf("%s\t",ip); if(showrange)printf("%s\t",range); if(showctry){if(showcode)printf("%s",code); else printf("%s",code2loc(code));} if(showeol)printf("\n"); } char*ip2code(char*ipstr) { long xip,ip; int mask; char*code,*sp; char s[256]=""; static char lastmatch[256]=""; int lastmatchmask=0; FILE*f; strcpy(lastmatch,""); if(!ipstr)return "??"; f=fopen(geofile,"r");if(!f)return "[Cannot open ip-geo.ids file.]"; xip=str2ip(ipstr);if(xip==0)return "??"; while(!feof(f)){ s[0]=0;fgets(s,255,f); if(s[0]=='#')continue; sp=strchr(s,' ');if(!sp)continue;sp++;code=sp; sp=strchr(s,'/');if(!sp)continue;sp++;mask=atoi(sp); ip=str2ip(s); if(maskmatch(xip,ip,mask)) {if(mask>lastmatchmask) {strcpy(lastmatch,s);lastmatchmask=mask;} if(showmatches) {sp=strchr(s,'\n');if(sp)sp[0]=0; sp=strchr(s,' ');if(sp){sp[0]=0;sp++;while(sp[0]==' ')sp++;} printcountry(ipstr,sp,s); } } } fclose(f); strncpy(matchrange,lastmatch,63);matchrange[63]=0; sp=strchr(matchrange,' ');if(sp)sp[0]=0; sp=strchr(lastmatch,'\n');if(sp)sp[0]=0; sp=strchr(lastmatch,' ');if(!sp)return "??";sp++; while(sp[0]==' ')sp++; return sp; } void showcountryranges(char*code) { FILE*f; char s[256],*sp; f=fopen(geofile,"r");if(!f){printf("[Cannot open ip-geo.ids file.]\n");return;} while(!feof(f)){ s[0]=0;fgets(s,255,f); if(s[0]=='#')continue; sp=strchr(s,'\n');if(sp)sp[0]=0; sp=strchr(s,' ');if(!sp)continue;sp[0]=0;sp++;while(sp[0]==' ')sp++; if(strcasecmp(code,sp))continue; printf("%s\n",s); } fclose(f); } void showcountry(char*ip) { char*code,*sp; sp=strchr(ip,'\n');if(sp)sp[0]=0; matchrange[0]=0; code=ip2code(ip); if(!showmatches)printcountry(ip,code,matchrange); } void showcountrylist() { char s[256]; while(!feof(stdin)) {s[0]=0;fgets(s,255,stdin); if(s[0]=='\n')continue; if(s[0]=='#')continue; if(!s[0])continue; showcountry(s); } } void help() { printf( "Usage: ip2loc [-i] [-c] IP ...\n" " ip2loc country_code\n" "Shows countries or country codes for IP addresses.\n" "\n" "Options:\n" " -i show IP\n" " -c show country as code instead as name\n" " -C do not show country\n" " -r show IP range\n" " -m show all matching ranges\n" " -n do not show trailing \\n\n" " -L show country code \n" " -R show IP ranges for country \n" " -G use as geolocation file instead of %s\n" "\n" "When IP is '-', the addresses are read from stdin.\n" ,geofile); } int main(int argc,char*argv[]) { char*ip; char*code; int t; if(argc==2)if(isalpha(argv[1][0])){printf("%s\n",code2loc(argv[1]));return 0;} for(t=1;t